我正在http://doc.akka.io/docs/akka/current/scala/fault-tolerance.html阅读有关akka容错的教程。文章末尾的代码片段和文本显示,如果Supervisor中Exvisor的SupervisorStrategy为Esclate,那么Supervisor会将其子节点中抛出的Exception强制转移给其主管,导致Supervisor重新启动并停止其所有子节点。我可以链接"停止所有孩子"从Akka源代码中获取Actor.scala源代码的动作,并理解这种行为。
def preRestart(reason: Throwable, message: Option[Any]): Unit = {
context.children foreach { child ⇒
context.unwatch(child)
context.stop(child)
}
postStop()
}
然后文章介绍了Supervisor2,它与Supervisor的不同之处在于添加了一个没有操作的preRestart方法。然后Supervisor2的孩子将在Exception的情况下生存,因为Supervisor2在preRestart钩子中什么也不做,而不是迭代它的子节点并停止它们中的每一个。但是,如下面的代码所示,孩子们重新启动并失去状态。
child3 ! new Exception("CRASH")
child3 ! "get"
expectMsg(0) // lose its state
我在IDE中使用断点来确认孩子的重启确实存在,并为孩子调用preRestart。
我的问题是我无法弄清楚孩子何时以及为何重新开始。你能说清楚吗?是否有任何我可以参考的主要或源代码来理解这种行为?
答案 0 :(得分:1)
孩子重新启动,因为在Exception
获得Escalate
过去Supervisor2
之后,这是用户监护人的默认监管策略。 Restart
策略会传递给Actor
Escalate
的所有Exception
。
如果Supervisor2
未覆盖preRestart
,则子Actor
将被停止并且根本不存在。
您似乎正在寻找的行为只有在Supervisor2
的主管改为使用Resume
策略来处理Exception
时才会发生。