我创建了 Master actor 和 child actor(使用来自 Master 的 router
创建)。
Master 收到一些 Job 并将这个 Job 拆分成小任务,然后将它们发送给子 Actor(到 routees)。
我试图解决的问题是如何在 child Actor 完成工作时正确通知我的主人?
在一些教程(Pi approximation 和 Scala In Action 书中的例子)中,Master actor 在收到 children 的响应后,试图将初始任务数组的大小与接收到的结果的大小进行比较:
if(receivedResultsFromChildren.size == initialTasks.size) {
// it's mean children finished their job
}
但我认为这是非常糟糕的,因为如果某个子actor抛出异常,那么它不会将结果发送回发送者(返回主),所以这个条件永远不会评估为
true
.那么如何正确地通知master所有 child 都完成了他们的工作呢?
我认为其中一种选择是
Broadcast(PoisonPill)
给 child 听然后听Terminated(
路由器)
消息(使用所谓的 deathWatch
)。可以解决吗?如果使用
Broadcast(PoisonPill)
更好,那么我是否应该注册一些监督策略,以便在异常情况下停止某些路由?因为如果发生异常,那么我知道routee将重新启动,这意味着Master actor永远不会收到Terminated(
路由器)
.这是正确的吗?
最佳答案
在 Akka 中,这实际上非常简单。
成功的 child 可以向父 Actor 发送一条普通的回复消息。来自失败actor的意外失败可以在监督策略中捕获并适当处理(例如,通过重新启动actor,或停止它并将其从要等待的actor列表中删除)。
所以它看起来像这样:
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
}
}
关于scala - Akka 。如何知道所有 child Actor 都完成了他们的工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30415353/