2013-05-30 80 views
3

我很困惑我在阿卡看到的行爲。簡而言之,我有一組演員進行科學計算(恆星形成模擬)。他們有一些狀態。當發生錯誤使得一個或多個進入無效狀態時,我想重新啓動整個設置以重新開始。如果單個calc(整個集合)花費太長時間(沒有辦法事先預測它可能運行多久),我也想這樣做。阿卡演員殺死/重新啓動行爲

因此,有在樹的底部的一組仿真演員,則它們上面董事(經由路由器創建它們,並且經由路由器發送它們的消息以及)。還有一個以上的Director級別可以在不同的機器上創建導演,並從他們那裏收集結果。

我使用阿卡計劃創建一個一次性的超時事件,在當地主管,當開始模擬處理超時的情況。當導演得到這個情況下,如果所有的仿真演員都沒有完成,它這樣做:

children ! Broadcast(Kill) 

,孩子們是擁有/創建它們的路由器 - 這發出了一個殺死所有的孩子們(SimulActors)。

我以爲會發生的是,所有的小演員將重新啓動。但是,它們的preRestart()鉤子方法從不被調用。我看到收到的殺戮消息,但就是這樣。

我必須缺少的東西在這裏根本。我已經閱讀了關於這個主題的Akka文檔,我不得不說我發現它們不夠明確(特別是主管頁面)。我非常感謝Kill/restart進程的詳細解釋,或者其他一些參考資料(Google並不是非常有用)。

回答

4

如果路由器的子進程終止時,路由器不會自動 產生一個新的孩子。如果路由器的所有孩子都有 終止路由器將自行終止

取自akka docs

+0

一個關鍵的句子,逃避我。:) –

0

我會考慮使用一個監管策略 - 阿卡已建行爲在殺害所有參與者(全部爲一個策略),你可以定義具體的策略 - 例如重啓。

我想運行此更慣用的方法是有演員拋出X異常,如果他們沒有在一段時間後完成,然後主管搞定通過監管策略。

你可以扔在孩子沒有做過異常,然後定義行爲,象這樣:

override val supervisorStrategy = 
    AllForOneStrategy(maxNrOfRetries = 0) { 
     case _: NotDoneException  ⇒ Stop 
     case _: Exception  ⇒ Restart 
    } 

明白,重啓意味着停止老演員,創造一個新的,獨立的對象/演員

這一點很重要

參考文獻:

http://doc.akka.io/docs/akka/snapshot/scala/fault-tolerance.html

http://doc.akka.io/docs/akka/snapshot/general/supervision.html

+0

剛看到你的答案。在我的應用程序中,要超時的actor不能拋出異常,因爲它在對第三方lib的調用中被阻止。這是關鍵所在。在這種情況下,我失去了對這位演員的控制。 –

+0

這可能爲時已晚,但您可以將該第三方電話包裹在未來內而不是阻止您的演員。你也可以在這個未來設置一個超時。 – Nabegh