2015-05-23 48 views
2

我創建了主演員和兒童演員(使用Master的router創建)。Akka。如何知道所有的兒童演員完成他們的工作

高手收到一些工作,並將這項工作分成小任務,並將它們發送給兒童演員(路由)。

我試圖解決的問題是,當兒童演員完成他們的工作時,我該如何正確通知我的主人?

在一些教程(Pi approximation和例如,從斯卡拉在行動書)碩士演員從兒童接受響應試圖比較任務的初始陣列收到的結果的大小尺寸後:

if(receivedResultsFromChildren.size == initialTasks.size) { 
    // it's mean children finished their job 
} 

但我認爲這很糟糕,因爲如果一些小孩演員拋出異常,那麼它不會將結果發回給發送者(回到主),所以這種情況永遠不會評估爲true

那麼如何正確地通知主人,所有的孩子都完成了他們的工作?

我覺得選項之一是Broadcast(PoisonPill)孩子,然後(使用所謂deathWatch)聽Terminated(路由器)消息。它可以解決嗎?

如果使用Broadcast(PoisonPill)更好,那麼我是否應該註冊一些監督策略,以防止異常情況下的某些routee?因爲如果發生異常,那麼routee將會重新啓動,正如我所知,這意味着主演將永遠不會收到Terminated(路由器)。這是對的嗎?

+0

有所謂的[aggerator模式](http://doc.akka.io/docs/akka/snapshot/contrib/aggregator.html) – jilen

回答

7

在阿卡,這其實很簡單。

成功的孩子可以發送一個普通的回覆消息給父母。失敗演員的意外失敗可以在監督策略中被捕獲,並得到適當處理(例如,通過重新啓動演員,或通過停止演員並將其從演員列表中刪除以等待)。

所以它可能是這個樣子:

var waitingFor = Set.empty[ActorRef] 

override def preStart() = ??? // Start the children with their subtasks 

override def supervisionStrategy = OneForOneStrategy() { 
    case _ => { 
     waitingFor -= sender() 
     if (waitingFor.isEmpty) ??? // processing finished 
     Stop 
    } 
} 

override def receive = { 
    case Reply => { 
     waitingFor -= sender() 
     if (waitingFor.isEmpty) ??? // processing finished 
    } 
} 
+1

在一般情況下,這似乎是一個好主意,即使對於不是兒童演員的工人演員也是如此。然而,我想解決一個稍微不同的問題:我想在所有的小孩演員都停下來的時候阻止演員。這裏最簡單的解決方案是什麼? –