12

I'm playing with Akka and I have a design in which a supervisor actor has a child playing role A and several children playing role B. I want to define a supervision policy such as A failures are escalated (terminating the supervisor) and B ones produces the individual actors to be restarted.

Is this possible? Is it advisable?

4

1 回答 1

11

是的,通过覆盖supervisorStrategy. 例如,来自文档

import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._

override val supervisorStrategy =
  OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
    case _: ArithmeticException      => Resume
    case _: NullPointerException     => Restart
    case _: IllegalArgumentException => Stop
    case _: Exception                => Escalate
  }

然后阅读注释:

如果策略是在监督参与者内部(而不是在伴随对象内)声明的,它的决策者可以以线程安全的方式访问参与者的所有内部状态,包括获取对当前失败的子节点的引用(可作为发送者使用)的失败消息)。

因此,与其匹配异常的类型,不如匹配发件人(只需在此处输入;它可能无法编译):

override val supervisorStrategy =
  OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
    if (sender == SomeSpecialChild) Escalate
    else Restart
  }

这没有什么问题,但是如果你有一群孩子扮演不同的角色,你可能应该遵循 Akka 的第一条规则(嗯,我的 Akka 的第一条规则):当有疑问时,你可能想要另一个演员。创建一个演员来监督角色 A 和另一个演员来监督角色 B。您仍然需要覆盖supervisorStrategy,但测试会更简单。并且更容易管理角色 A 和 B 之间的任何其他特殊差异。

于 2014-01-21T23:15:17.990 回答