Akka演员的Kill/重启行为

3
我对Akka中的行为感到困惑。简单来说,我有一组执行科学计算(星形成模拟)的演员。它们有一些状态。当发生错误导致一个或多个进入无效状态时,我希望重新启动整个集合以重新开始。如果单个计算(在整个集合上)花费的时间太长(无法预测运行时间),我也想这样做。
因此,在树底部有一组Simulation演员,然后是它们上面的Director(通过路由器创建它们,并通过该路由器发送消息)。再上面有一个更高级别的Director,用于在不同的机器上创建Directors并收集它们的所有结果。
我通过使用Akka调度程序在本地Director中创建一次性超时事件来处理超时情况。当Director收到此事件时,如果其所有Simulation演员尚未完成,则会执行以下操作:
children ! Broadcast(Kill)

children是拥有/创建它们的路由器 - 这将向所有子级(SimulActors)发送一个Kill信号。

我原以为会重新启动所有子级演员。 但是,它们的preRestart()钩子方法从未被调用。 我看到了收到的Kill消息,但就这样。

我一定是缺少了一些基本的东西。 我已经阅读了关于此主题的Akka文档,并且我必须说我觉得它们不太清楚(特别是Supervisors页面)。 我非常希望能够获得有关Kill / restart过程的详细说明,或者其他参考资料(谷歌并没有提供很多帮助)。

2个回答

4

注意

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

摘自akka文档


让我困惑的那个至关重要的句子。 :) - Scala Newb

0

我会考虑使用监督策略 - akka内置了用于杀死所有actor的行为(全员策略),您可以定义具体的策略 - 例如重新启动。

我认为更符合惯用方式的方法是,如果演员在一段时间后没有完成,则让它们抛出x异常,然后由监管者通过监督策略处理。

您可以从子进程中抛出未完成的异常,然后像这样定义行为:

override val supervisorStrategy =
    AllForOneStrategy(maxNrOfRetries = 0) {
      case _: NotDoneExceptionStop
      case _: ExceptionRestart
    }

重启意味着停止旧的actor并创建一个新的独立对象/actor,理解这一点非常重要。
参考文献:

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

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


刚看到你的回答。在我的应用程序中,一个即将超时的actor无法抛出异常,因为它被阻塞在对第三方库的调用上。这就是问题的关键。在这种情况下,我已经失去了对该actor的控制。 - Scala Newb
这可能有点晚了,但是你可以将第三方调用包装在一个future中,而不是阻塞你的actor。你也可以在该future上设置超时。 - Nabegh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接