Akka deathwatch - 观看终结和重启

时间:2016-06-22 12:49:09

标签: akka

我有两个演员,父母和孩子。父母使用content.watch(孩子)观看孩子。如果子进程调用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
  }
}

父作者如何监视孩子并观察任何终止/重启?

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

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

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

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

我工作但看起来有点像黑客。还有其他我不知道的选择吗?

非常感谢!

2 个答案:

答案 0 :(得分:0)

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

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

如果手动抛出异常,或者直接抛出包装异常,就更容易了。

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

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

答案 1 :(得分:0)

Akka演员监督策略更侧重于处理异常,并且可以基于异常来决定要采取的行动。

在您的情况下,您希望使其基于actor,如果是这种情况,则不同类型的actor必须返回不同的异常。

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