11

如果我像这样创建一个日志演员

val logger: ActorRef =
    actorSystem.actorOf(Props(new Logger()))

并且记录器由于异常重新启动,我的记录器停止写入磁盘。

我一直在发消息logger ! msg

我是否正确假设当主管重新启动我的日志演员时 ActorRef 没有更新?

4

1 回答 1

17

ActorRef应该由 Akka 正确更新以指向演员的新实例。文档明确指出:

指向终止的actor的引用不等于指向另一个(重新创建的)具有相同路径的actor的引用。请注意,由失败引起的actor重启仍然意味着它是同一个actor化身,即重启对于 ActorRef 的消费者是不可见的

也在这里

当调用 actorOf() 时,它会将传递的 Props 所描述的 actor 的化身分配给给定的路径。演员化身由路径和 UID 标识。重启只会交换由 Props 定义的 Actor 实例,但化身和 UID 保持不变。

当演员停止时,化身的生命周期结束。此时会调用适当的生命周期事件,并通知观察参与者终止。化身停止后,可以通过使用actorOf()创建一个actor来再次重用路径。在这种情况下,新化身的名称将与前一个相同,但 UID 将不同。...

ActorRef 总是代表一个化身(路径和 UID),而不仅仅是一个给定的路径。因此,如果停止了一个演员并创建了一个具有相同名称的新演员,则旧化身的 ActorRef 将不会指向新演员。

这是使用 s 的主要优点之一ActorRef,否则与演员一起工作会更加不方便。

您需要检查您的主管策略并确保实际重新启动了actor。默认策略是:

final val defaultStrategy: SupervisorStrategy = {
  def defaultDecider: Decider = {
    case _: ActorInitializationException ⇒ Stop
    case _: ActorKilledException         ⇒ Stop
    case _: Exception                    ⇒ Restart
  }
  OneForOneStrategy()(defaultDecider)
}

因此,如果你得到一个Exception你的演员将被重新启动并且ActorRef应该是有效的,但是如果你得到其他类型的Throwable那么它将被停止并且ActorRef将变得无效。

于 2016-02-11T10:42:13.580 回答