Akka演员与期货交换工作

时间:2013-01-14 10:08:34

标签: scala akka

我正在尝试在akka演员之间建立一个消息传递过程来代表主人给工人一份工作,并密切关注它。我的问题是

  1. 我的建议是在合理的方法之下,
  2. 即使它是 不,我想知道如何通过合成来正确完成 期货,为了我未来的教育。
  3. 我喜欢这个过程

    1)主人使用ask向工作人员发送工作。它希望在5秒内得到答复,否则它认为工人失去了它的机会,它将不得不再次进入竞标。

    import context.dispatcher
    implicit val timeout = Timeout(5 seconds)
    val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[Future[WorkCompleted]]
    

    2a)如果工作人员在5秒钟内没有响应,我希望主人向自己发送一条消息,说明要重新分配工作。

    self ! WorkAllocationFailed(work, worker)
    

    2b)如果工作人员确实做出了回应,那么它会给我们一个未来[WorkCompleted]。我想等待那个未来完成,比如2分钟。

    3a)如果Future [WorkCompleted]未能在超时内完成,则重新分配工作

    self ! WorkFailed(work, worker)
    

    3b)如果Future [WorkCompleted]成功,则收集结果

    我尝试过创建这个逻辑,但是我遇到了嵌套onComplete的混乱,我不知道如何在Future [WorkCompleted]上执行超时。我尝试阅读Akka 2.10 Futures docs,但无法找到解决方案。

2 个答案:

答案 0 :(得分:2)

一般的想法是,你有一个将工作交给工人池的大师是一个合理的模式。

另一方面,当系统的所有部分都已经是演员时,我不建议使用期货。您可以通过tell发送,而不是使用ask提交作品。然后,主人可以定期检查超时工作,然后重新提交。

此外,在actor的主体中调用onComplete非常危险,因为它在可能不同的线程上执行。与演员沟通的安全方式是通过消息传递。如果你有一个Future,并且你希望在Future完成时在actor中完成某些事情,那么最好使用管道模式。

您的代码段中还有一个小错误。如果你的工作者回复了WorkCompleted,那么这就是你真正想要的那条线:

val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[WorkCompleted]

答案 1 :(得分:2)

我同意恩德雷的回答 - 所有非常好的观点。

这个怎么样:

1)为超时安排一条消息(使用system.scheduler.scheduleOnce

2)使用常规tell

将工作消息发送给工作人员

3a)如果完成的工作在超时消息之前返回,则取消预定作业并使用步骤1和2重新分配工作

3b)如果完成的工作在超时消息之后返回,则忽略它或取消重新分配的工作。

一个地方的期货可能对工人有帮助,特别是如果工作需要很长时间或阻塞。工作人员可以使用未来来完成工作并保持可用以处理更多传入消息,例如取消工作。