如何检测Akka演员何时完成?

时间:2015-05-29 14:01:51

标签: scala akka actor

我正在尝试实现一个简单的应用程序,我将不同的任务分配给Akka actor并让它们独立地计算结果。问题是如何检测所有何时完成分配的作业(成功或失败计数),因为我需要从中获取计算结果。什么是典型的方法?

我尝试使用system.shutdown()等待所有actor完成,但是过去这个命令actor已经终止,并且不响应任何所需的消息以便检索计算结果。

我想到的另一件事是将JobCompleted消息从工作者演员发送到他们的父母。然后我可以算一下我收到的这种消息有多少,如果计数等于工人演员产生,我们知道他们都已经完成了。虽然我不知道当演员内部的失败发生时会发生什么。这种方法似乎太笨重了。

3 个答案:

答案 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

由于这些是结果的未来,您可以根据成功/失败对它们进行映射并适当地使用它们

http://doc.akka.io/api/akka/2.0/akka/pattern/package.html

答案 2 :(得分:0)

我会有一个协调的演员,它会产生工人,然后发送每条消息来指定它要做的工作,构建一个包含每个工人的ActorRefs的集合。当在协调员中收到JobCompleted(或者,如果合适的话,JobFailed)消息时,累积结果并从该集合中删除该消息的发送者(即,Worker的ActorRef)。当集合为空时,所有工作人员都已完成。工作人员自己可以在发送信息后立即致电context.stop(self)终止自己。

进一步的语义将取决于工作的具体情况。例如,协调员可以建立一个自己的预定呼叫(例如,呼叫context.system.scheduler.schedule(someDelay, someDelay, self, ResendWorkOrders)将在每someDelay个间隔后向自己发送一个ResendWorkOrders消息。当它获得该调用时,它可以将工作请求重新发送给集合中剩余的每个工作者(甚至重新生成它们)。当集合为空(所有工作者都已完成)时,可以取消调度(对调度程序的调用返回Cancellable)。例如,这可以处理可能无法向工作人员传递消息的情况(例如,在分布式系统中),或者工作人员可能在不回复协调员的情况下发生故障或错误的情况。