鎮圖:actor内功心法圖
actor的生命周期可以用hooks展現和控制,下面是預設的actor hooks的方法,我們可以選擇性的進行重寫:
每個hooks,在不同的政策下調用次數及順序是不同的,那什麼是政策?:
政策,比如restart,實際上就是執行了一系列的方法包括:prerestart,postrestart
start政策,調用prestart hook,一般用于初始化資源.在建立一個actor的時候,會調用構造函數,之後調用prestart,那這兩個方法有什麼差別呢,資源初始化是放在構造函數,還是放在prestart裡面呢?在restart政策裡面會詳細介紹。
poststop hook 一般用于回收資源。actor在被調用poststop之前,會将郵箱中剩下的message處理掉(新的消息變成死信了)。actor是由uid和path來唯一辨別的,也就是說actorref也是通過uid和path來定位。在actor被stop之後,新的actor是可以用這個path的,<code>但是舊的actorref是不能用的,因為uid不一樣。</code>
restart政策是最為複雜的一種情況,先上個圖:
在預設情況下,restart政策會:
actor被挂起
調用舊執行個體的 supervisionstrategy.handlesupervisorfailing 方法 (預設實作為挂起所有的子actor)
調用prerestart方法,從上面的源碼可以看出來,prerestart方法将所有的children stop掉了!(stop動作,大家注意!),并調用poststop回收資源
調用舊執行個體的 supervisionstrategy.handlesupervisorrestarted 方法 (預設實作為向所有剩下的子actor發送重新開機請求)
等待所有子actor終止直到 prerestart 最終結束
再次調用之前提供的actor工廠建立新的actor執行個體
對新執行個體調用 postrestart
恢複運作新的actor
<code>restart政策,和stop政策有什麼不同的地方?</code>
stop政策會調用poststop(),restart政策也會調用poststop(),但是restart政策不是通過stop政策來停止舊的actor,uid和path都沒變。也就是說,在被restart之後,不用重新擷取actorref.
<code>prerestart hook有什麼特别之處?</code>
預設的prerestart hook會将所有的children通過stop政策停止,這個時候children就是通過stop政策->start政策啟動的,而不是被遞歸restart.那有什麼影響?如果有外部的actor持有舊的chidren actorref,那這個ref就是不能用的,因為雖然path是對的,但是uid已經變了!
<code>postrestart hook有什麼特别之處?</code>
預設postrestart是調用prestart(),這樣在重新開機的過程中,構造函數和prestart方法都會被重新調用,<code>如果有個資源隻想初始化一次,那麼就必須重寫掉這個方法</code>.是以一般建立children是放在prestart裡面。
<code>被重新開機後,如何繼承舊的actor的狀态?</code>
通過将state轉儲到:
非jvm級别的crash,使用靜态類儲存狀态