在Akka消息中发送期货好吗?

时间:2015-12-16 16:09:13

标签: scala akka actor concurrent.futures

我正致力于实现一种小语言来将任务发送到执行和控制执行流程。在将任务发送到我的系统之后,用户获得了一个未来(在其上可以调用阻塞的get()或flatMap())。我的问题是:在Akka消息中发送期货是否可以?

示例:actor A向actor B发送消息 Response Response 在其字段中包含未来。然后在某个时刻A将履行创造未来的承诺。收到响应后,B可以随时调用flatMap()或get()。

我问,因为Akka消息应该是不可变的,即使actor在不同的JVM上也能工作。如果演员A和B在不同的JVM上,我不知道上面的例子是如何工作的。另外,即使actor在同一个JVM上,我的例子也有问题吗?

在接受的答案in this stackoverflow question中完成了类似的事情。如果演员在不同的JVM上,这会起作用吗?

2 个答案:

答案 0 :(得分:5)

没有遥控它可能,但仍然不可取。通过远程操作,它根本不会起作用。

如果您的目标是让API返回Future,但使用actor作为下面的管道,一种方法可能是API在内部创建自己的actor ask,并且然后将该问题的未来返回给调用者。由API调用生成的actor保证是API实例的本地,并且可以通过常规tell / receive机制与actor系统的其余部分进行通信,因此没有{{1作为消息发送。

Future

其中class MyTaskAPI(actorFactory: ActorRefFactory) { def doSomething(...): Future[SomethingResult] = { val taskActor = actorFactory.actorOf(Props[MyTaskActor]) taskActor ? DoSomething(...).mapTo[SomethingResult] } } 收到MyTaskActor,捕获发件人,发出任务进程请求,DoSomething可能become收到最终响应捕获状态的SomethingResult发送者和停止自己。这种方法为每个请求创建两个actor,一个显式地MyTaskActor,一个隐含地,ask的处理程序,但是将所有状态保存在actor中。

或者,您可以使用ActorDSL创建一个内联doSomething的演员,并使用捕获的Promise完成而不是使用ask

class MyTaskAPI(system: System) {

   def doSomething(...): Future[SomethingResult] = {
     val p = Promise[SomethingResult]()
     val tmpActor = actor(new Act {
       become {
         case msg:SomethingResult => 
            p.success(msg)
            self.stop()
       }
     }
     system.actorSelection("user/TaskHandler").tell(DoSomething(...), tmpActor)
     p.future
   }
 }

这种方法有点偏离我的头脑,它确实使用API​​和临时演员之间的共享值,有些人可能会认为这是气味,但应该知道如何实现你的工作流程。

答案 1 :(得分:0)

如果你问是否可能,那么是的,这是可能的。远程actor基本上是进程间通信。如果你将两台机器上的所有东西都设置为可以正确处理未来的状态,那么它应该是好的。你没有提供任何有用的例子,所以我无法深入研究它。