Classic Actor | Lifecycle
本文总结class Actor的生命周期的内容。官网文档
一个Actor能够创建任意数据数量的子Actor,而子Achtor也能够重复上面的行为,从而形成一个Actor的层次结构。ActorSystem托管该层次结构,且会指定一个位于层次结构顶端的Root Actor。子Actor的生命周期会和父actor是相关联的,子actor能够被自己或者父actor Stop;当父actor进行Stop时,会stop所有的子actor,因此子actor不能独立于父actor。
生命周期
在actor system中,一个path可能会被一个活动的actor所占据。起初,path是为空的,当actorOf()被调用时就会就根据Props生成一个actor incarnation分配给path。actor incarnation由path和UID标记,且一个actor incarnation会拥有一个用于存储待处理消息队列-Mailbox。
当actor触发重启时,old actor会先触发preRestart()钩子函数,在new actor在初始化之后会调用postRestart()钩子函数,默认下postRestart()会调用preStart(),就像正常启动actror一样。actor重启只替换actual actor object,mailbox的内容是不受restart影响的,因此消息处理在postRestart()返回后继续,触发异常的消息不再处理。在actor重新启动后时发给它的任何消息都将像往常一样排队在它的mailbox。
当actor调用stop时,incarnation的生命周期也就结束了。actor可以通过四种方式来stop,在stop期间会stop自己所有子actor,并且发送消息给Watchers和让mailbox disable。 在stopped之后会调用postStop钩子函数,在postStop里面定义资源清理动作。在actor stopped之后,其path能够被重用的。
restart & stop ,followed by re-creation of actor
restart。会替换有Props定义的Actor实例,而incarnation和UID会保持不变。因为incarnation是相同的,因此ActorRef依然可以使用。
stop ,followed by re-creation of actor。上文说到在actor stopped之后,其path是能够被重用滴,该path能够通过actorOf()重新创建,在这种情况下,new incarnation 会和old incarnation的name相同,但UID不同。
一个ActorRef不是代表一个path而是代表一个actor incarnation(path 和 UID),所以当一个actor在stopped后再创建一个同名的actor,旧的ActorRef是不会指向新的actor incarnation。
相对的,ActorSelection就是指向一个path(在使用通配符时可指向多个path),且ActorSelection完全无视当前会有哪个actor incarnation 正在占用path。基于这个原因,ActorSelection是不能被够观察 。解析存活在当前path下的actor incarnation的ActorRef是可能的, 通过发送Identify给ActorSelection,它能够回复一个含有正确reference的ActorIdentify.
四个钩子函数
Actor提供了四个生周期钩子函数:
preStart()
在启动actor之后被调用。在第一次创建actor时调用此方法。在重新启动期间,它由postRestart的默认实现调用,这意味着通过覆盖该方法,您可以选择该方法中的初始化代码是只对该actor调用一次,还是对每次重新启动都调用一次。初始化代码是actor构造函数的一部分,它总是在创建actor类的实例时被调用,每次重新启动时都会发生
postStop()
在停止一个actor之后,它的postStop钩子被调用,进行一些资源清理的工作,例如它可能被用于从其他服务取消该actor的注册。这个钩子保证在actor的消息队列被禁用后运行。
preRestart(reason, message)
如果在处理消息时抛出异常,可以选择重新启动actor(可通过监督策略设置),过程会调用preRestart.
postRestart()
在new actor初始化后,会调用postRestart,默认情况下postRestart会直接调用preRestart.
Attention
- 每个Actor是需要显式地start和stop的有状态资源。
- 当Actor不再引用时是不会自动停止,被创建的Actor必须显式地销毁,唯一的简化是停止父参与者也会递归地停止父参与者创建的所有子参与者。
- 当ActorSystem shut dowm时,所有的Actors会自动被stop