我对在Akka看到的行为感到困惑。简而言之,我有一组演员进行科学计算(恒星形成模拟)。他们有一些国家。当发生错误使得一个或多个进入无效状态时,我想重新启动整个集合以重新开始。如果单个计算(在整个集合中)花费的时间太长(我无法事先预测它可以运行多长时间),我也想这样做。
因此,树底部有一组模拟演员,然后是他们之上的导演(通过路由器创建它们,并通过该路由器发送消息)。还有一个以上的Director级别可以在不同的机器上创建Director并从中收集所有的结果。
我通过使用Akka Scheduler在模拟开始时在本地Director中创建一次性超时事件来处理超时情况。当Director获得此事件时,如果其所有模拟演员尚未完成,则执行以下操作:
children ! Broadcast(Kill)
其中children是拥有/创建它们的路由器 - 这会向所有子节点发送一个Kill(SimulActors)。
我认为会发生的是所有的儿童演员都会重新开始。但是,永远不会调用它们的preRestart()钩子方法。我看到收到的Kill消息,但就是这样。
我必须遗漏一些基本的东西。我已经阅读了关于这个主题的Akka文档,我不得不说我发现它们不太明确(特别是关于主管的页面)。我非常感谢对杀戮/重启过程的全面解释,或者只是其他一些参考(谷歌不是很有帮助)。
答案 0 :(得分:4)
请注意
如果路由器的子节点终止,则路由器不会自动进行 产生一个新的孩子。如果路由器的所有孩子都有 终止路由器将自行终止。
取自akka docs。
答案 1 :(得分: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