如果我像这样创建一个伐木演员
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
将变得无效。