当主管重新启动关联的Actor时,是否更新了ActorRef?

kli*_*iew 9 scala akka akka-supervision akka-actor

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

val logger: ActorRef =
    actorSystem.actorOf(Props(new Logger()))
Run Code Online (Sandbox Code Playgroud)

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

我一直在发短信 logger ! msg

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

yǝs*_*ǝla 14

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

指向已终止的actor的引用不会与指向具有相同路径的另一个(重新创建的)actor的引用进行比较.请注意,由故障引起的actor的重启仍然意味着它是相同的actor化身,即对于ActorRef的使用者而言不可见重启.

还在这里:

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

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

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

这是使用ActorRefs 的主要优点之一,否则与演员合作会更加不方便.

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

final val defaultStrategy: SupervisorStrategy = {
  def defaultDecider: Decider = {
    case _: ActorInitializationException ? Stop
    case _: ActorKilledException         ? Stop
    case _: Exception                    ? Restart
  }
  OneForOneStrategy()(defaultDecider)
}
Run Code Online (Sandbox Code Playgroud)

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