我正在尝试实现一个简单的应用程序,我将不同的任务分配给Akka actor并让它们独立地计算结果。问题是如何检测所有何时完成分配的作业(成功或失败计数),因为我需要从中获取计算结果。什么是典型的方法?
我尝试使用system.shutdown()等待所有actor完成,但是过去这个命令actor已经终止,并且不响应任何所需的消息以便检索计算结果。
我想到的另一件事是将JobCompleted消息从工作者演员发送到他们的父母。然后我可以算一下我收到的这种消息有多少,如果计数等于工人演员产生,我们知道他们都已经完成了。虽然我不知道当演员内部的失败发生时会发生什么。这种方法似乎太笨重了。
答案 0 :(得分:2)
可能重复:
Knowing when akka actors are finished
Akka tracking when the actors finished
最简单的开箱即用方式:使用询问模式并等待所有返回的期货。在 for 块或通过Future.sequence (有关更多信息,请参阅官方文档)
此外,如果您需要在任务完成后立即终止 - 有许多不同的方法。例如,请参阅此http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2
答案 1 :(得分:0)
当您创建"工作"并将它们发送给工作者,您可以使用ask模式创建结果的Future。
这看起来像是:
val myActorRef = system.actorOf(Props(classOf[WorkerActor]), "worker")
val result = (myActorRef ? SomeComputationMessage()).mapTo[Result]
如果actor通过sender ! Result()
将结果发送回调用者,则此ask模式将返回带结果的Future
由于这些是结果的未来,您可以根据成功/失败对它们进行映射并适当地使用它们
答案 2 :(得分:0)
我会有一个协调的演员,它会产生工人,然后发送每条消息来指定它要做的工作,构建一个包含每个工人的ActorRefs的集合。当在协调员中收到JobCompleted(或者,如果合适的话,JobFailed)消息时,累积结果并从该集合中删除该消息的发送者(即,Worker的ActorRef)。当集合为空时,所有工作人员都已完成。工作人员自己可以在发送信息后立即致电context.stop(self)
终止自己。
进一步的语义将取决于工作的具体情况。例如,协调员可以建立一个自己的预定呼叫(例如,呼叫context.system.scheduler.schedule(someDelay, someDelay, self, ResendWorkOrders)
将在每someDelay
个间隔后向自己发送一个ResendWorkOrders消息。当它获得该调用时,它可以将工作请求重新发送给集合中剩余的每个工作者(甚至重新生成它们)。当集合为空(所有工作者都已完成)时,可以取消调度(对调度程序的调用返回Cancellable
)。例如,这可以处理可能无法向工作人员传递消息的情况(例如,在分布式系统中),或者工作人员可能在不回复协调员的情况下发生故障或错误的情况。