【问题标题】:Why does a supervisor restart its children after overriding the supervisor's preRestart hook to have it refrain from stopping its children in akka?为什么主管在覆盖主管的 preRestart 钩子以使其停止在 akka 中停止其孩子之后重新启动其孩子?
【发布时间】:2017-03-19 00:33:04
【问题描述】:

我正在http://doc.akka.io/docs/akka/current/scala/fault-tolerance.html 阅读有关 akka 容错的教程。文章末尾的代码 sn-ps 和文本显示,如果 Supervior 中异常的 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。

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

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    孩子被重启是因为这是用户监护人在Exception 得到Escalated 超过Supervisor2 之后的默认监督策略。 Restart 策略被传递给Escalated 和Exception 的所有Actors。

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

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

    【讨论】:

    • 谢谢。您能否建议我可以在 Akka 源代码中参考“重启策略被传递给所有升级异常的 Actor”的地方。我还没有找到与此行为相关的源代码。
    猜你喜欢
    • 2014-11-18
    • 2014-12-09
    • 2011-07-26
    • 2017-05-02
    • 1970-01-01
    • 2023-03-13
    • 2016-04-10
    • 2015-02-08
    • 1970-01-01
    相关资源
    最近更新 更多