3

我对在 Akka 中看到的行为感到困惑。简而言之,我有一组执行科学计算(恒星形成模拟)的演员。他们有一些状态。当发生错误导致一个或多个进入无效状态时,我想重新启动整个集合以重新开始。如果单个计算(在整个集合中)花费的时间太长(无法提前预测它可能运行多长时间),我也想这样做。

因此,在树的底部有一组模拟参与者,然后是它们上方的 Director(通过路由器创建它们,并通过该路由器向它们发送消息)。在此之上还有一个 Director 级别,可以在不同的机器上创建 Director 并从它们中收集结果。

我通过使用 Akka 调度程序在本地 Director 中创建一次性超时事件来处理超时情况,当模拟开始时。当 Director 得到这个事件时,如果它的所有 Simulation actor 都没有完成,它会这样做:

children ! Broadcast(Kill)

其中 children 是拥有/创建它们的路由器 - 这会向所有孩子(SimulActors)发送一个 Kill。

我认为会发生的是所有子演员都将重新启动。但是,它们的 preRestart() 钩子方法永远不会被调用。我看到收到的 Kill 消息,但仅此而已。

我必须在这里遗漏一些基本的东西。我已经阅读了关于这个主题的 Akka 文档,我不得不说我发现它们不太清楚(尤其是关于 Supervisors 的页面)。我真的很感激对 Kill/restart 过程的彻底解释,或者只是一些其他参考资料(谷歌不是很有帮助)。

4

2 回答 2

4

笔记

如果路由器的子节点终止,路由器将不会自动生成新的子节点。如果路由器的所有子节点都已终止,则路由器将自行终止

取自akka 文档

于 2013-05-30T16:10:23.597 回答
0

我会考虑使用监督策略 - akka 内置了杀死所有参与者的行为(全部用于一个策略),您可以定义特定的策略 - 例如重新启动。

我认为运行它的更惯用的方法是让演员在一段时间后没有完成时抛出 x 异常,然后主管通过监督策略处理该异常。

您可以从孩子那里抛出一个未完成的异常,然后像这样定义行为:

override val supervisorStrategy =
    AllForOneStrategy(maxNrOfRetries = 0) {
      case _: NotDoneException      ⇒ Stop
      case _: Exception     ⇒ Restart
    }

重要的是要理解重启意味着停止旧的 Actor 并创建一个新的单独的对象/Actor

参考:

http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html

http://doc.akka.io/docs/akka/snapshot/general/supervision.html

于 2013-06-02T14:40:44.177 回答