为什么主管在覆盖主管的preRestart挂钩之后重启其子女,以避免在akka中阻止其子女?

时间:2017-03-16 10:53:45

标签: scala akka

我正在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。

我的问题是我无法弄清楚孩子何时以及为何重新开始。你能说清楚吗?是否有任何我可以参考的主要或源代码来理解这种行为?

1 个答案:

答案 0 :(得分:1)

孩子重新启动,因为在Exception获得Escalate过去Supervisor2之后,这是用户监护人的默认监管策略。 Restart策略会传递给Actor Escalate的所有Exception

如果Supervisor2未覆盖preRestart,则子Actor将被停止并且根本不存在。

您似乎正在寻找的行为只有在Supervisor2的主管改为使用Resume策略来处理Exception时才会发生。