【问题标题】:Akka deathwatch - watching for Terminations and RestartsAkka 死亡守望 - 监视终止和重启
【发布时间】:2016-06-22 12:49:08
【问题描述】:

我有两个演员,父母和孩子。父母使用 content.watch(child) 监视孩子。如果孩子调用 context.stop(self),则父母会收到一条 Terminated 消息。但是,如果子进程抛出异常,akka 会重新启动它,但它不会向父进程发送 Terminated 消息。

class Parent ... {
  def receive = {
    case "start" =>
      val child = ...
      context.watch(child)
      child ! "throw"
    case Terminated(actor) => logger.error(s"$actor died"")
  }
}

class Child ... {
  def receive = {
    case "stop" => context.stop(self) // parent is notified
    case "throw" => throw new Exception("oops") // parent is not notified
  }
}

父actor如何监控子actor并观察任何终止/重启?

我想出的一个选项是覆盖父级中的主管策略以停止任何异常:

class Parent ... {
  override val supervisorStrategy = OneForOneStrategy() {
    case _: Exception => Stop
  }
}

据我了解,这将适用于该演员的所有孩子。理想情况下,我想为个别孩子(演员类型)制定不同的主管策略,所以我想使用

class Child ... {
  override def postRestart(reason: Throwable): Unit = context.stop(self) 
}

我工作,但它似乎有点像一个黑客。还有其他我不知道的选项吗?

非常感谢!

【问题讨论】:

    标签: akka


    【解决方案1】:

    我不知道任何每个actor类型的监督模型,但我想到的是你可以在子actor中捕获异常并将其包装到一个信封中:

    try {
      ...
    } catch {
      case e: Throwable => throw new DontRestartMeException(e)
    }
    

    或者如果你手动抛出异常更简单,直接抛出被包裹的异常。

    然后在父级中决定每个异常类型:

    override val supervisorStrategy = OneForOneStrategy() {
        case e: DontRestartMeException => Stop
        case _: Exception => Restart
    }
    

    【讨论】:

    • 谢谢,我会看看这个想法
    【解决方案2】:

    Akka actor 监督策略更侧重于处理异常,并且您可以根据异常决定要遵循的操作。

    在你的情况下,你想让它基于演员,如果是这种情况,不同类型的演员必须返回不同的异常。

    因此,最好根据异常类型采取措施。如果不是这种情况并且抛出了类似的异常,那么最好将它们包装在 actor 级别,然后返回到更高级别的 actor。

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 2017-01-31
      相关资源
      最近更新 更多