我正致力于实现一种小语言来将任务发送到执行和控制执行流程。在将任务发送到我的系统之后,用户获得了一个未来(在其上可以调用阻塞的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上,这会起作用吗?
答案 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基本上是进程间通信。如果你将两台机器上的所有东西都设置为可以正确处理未来的状态,那么它应该是好的。你没有提供任何有用的例子,所以我无法深入研究它。