2015-05-23 47 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

在一般情况下,这似乎是一个好主意,即使对于不是儿童演员的工人演员也是如此。然而,我想解决一个稍微不同的问题:我想在所有的小孩演员都停下来的时候阻止演员。这里最简单的解决方案是什么? –