如果我像这样创建一个伐木演员

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


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

我一直在发送邮件logger ! msg

我是否可以假设主管重启我的日志记录actor时ActorRef没有更新?

最佳答案

ActorRef应该由Akka正确更新,以指向参与者的新实例。 docs明确指出:


指向终止的演员的引用不等于
指向具有相同路径的另一个(重新创建的)actor的引用。
请注意,由故障导致的actor重新启动仍然意味着
这是同一演员的化身,即,对于
ActorRef的消费者。


here


调用actorOf()时,它会分配actor的化身
由传递的道具描述到给定的路径。演员的化身
由路径和UID标识。重新启动仅交换Actor
道具定义的实例,但化身以及因此的UID
保持不变。

当角色停止时,化身的生命周期结束。在
相应的生命周期事件将被调用并观察
通知演员终止。化身之后
停止后,可以通过创建一个具有
actorOf()。在这种情况下,新化身的名称为
与上一个相同,但UID会有所不同。 ...

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


这是使用ActorRef的主要优点之一,否则与参与者一起工作将更加不便。

您需要检查主管策略,并确保角色实际上已重新启动。
默认策略是:

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


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

08-04 12:17