【问题标题】:Akka OneForOneStrategy does not workAkka OneForOneStrategy 不起作用
【发布时间】:2014-03-27 14:48:52
【问题描述】:

我有以下代码:

class A extends Actor with ActorLogging {
  override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 2) { 
    case _ => log.info("An actor has been killed"); Restart 
  }

  val b = context.system.actorOf(Props[B], "b")

  def receive = {
    case _ => context.system.scheduler.schedule(5 seconds, 5 seconds, b, true)
  }
}

class B extends Actor with ActorLogging {
  def receive = { case true => self ! Kill }
}

在演员A 的实例中self ! Kill 之后,我没有看到消息“演员已被杀死”,随后对演员A 的调用会生成“死信”消息,因此没有重新启动。为什么OneForOneStrategy 没有被调用?

奇怪的是,我可以删除整个 OneForOneStrategy 覆盖并且程序行为没有任何变化。

【问题讨论】:

    标签: scala akka actor fault-tolerance


    【解决方案1】:

    val b = context.system.actorOf(Props[B], "b") 应更改为 val b = context.actorOf(Props[B], "b") 以使新演员成为孩子,而不是顶级演员。

    【讨论】:

      【解决方案2】:

      您同时重新启动演员“B”,然后在重新启动时抛出异常。从您的 postRestart 代码中删除 self ! true。否则,你期望会发生什么?您将其发送到无限递归的重启循环中。

      以下是您所看到的顺序或动作来说明它:

      1. 创建演员“A”
      2. 创建演员“B”
      3. 发送true给A
      4. 发送true给B
      5. “B”在true 消息处引发异常
      6. “A”重新启动“B”
      7. 重启后“B”发送自己true
      8. 重复步骤 5

      【讨论】:

      • 好的,但是maxNrOfRetries = 2 应该做什么呢?我当然知道无限循环,但我认为它应该在父演员A 两次重试后终止,因为这个选项。
      • @Anton 好吧,如果 postRestart 被调用,则意味着 Actor 已成功重新启动。所以重试次数是1。
      • 我还是不明白。我看到它的方式应该是这样的:开始->失败->重新启动#1->失败->重新启动#2->失败->停止,因为maxNrOfRetries = 2。我错过了什么吗?
      • @Anton 最大重试次数是尝试重新启动 Actor 的最大次数,并在重新启动成功后重置。这不是 Actor 重启的最大次数。
      • 好的,谢谢。我已经简化了我的代码并删除了递归,因为它与我的问题的本质并不真正相关。
      猜你喜欢
      • 1970-01-01
      • 2015-11-16
      • 2018-04-07
      • 1970-01-01
      • 2023-03-23
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 2015-10-23
      相关资源
      最近更新 更多