如果我像这样创建一个日志演员
val logger: ActorRef =
actorSystem.actorOf(Props(new Logger()))
并且记录器由于异常重新启动,我的记录器停止写入磁盘。
我一直在发消息logger ! msg
我是否正确假设当主管重新启动我的日志演员时 ActorRef 没有更新?
如果我像这样创建一个日志演员
val logger: ActorRef =
actorSystem.actorOf(Props(new Logger()))
并且记录器由于异常重新启动,我的记录器停止写入磁盘。
我一直在发消息logger ! msg
我是否正确假设当主管重新启动我的日志演员时 ActorRef 没有更新?
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
将变得无效。