我正在努力实现一种小语言来将任务发送到执行和控制执行流程.在将任务发送到我的系统之后,用户获得了一个未来(在其上可以调用阻塞的get()或flatMap()).我的问题是:在Akka消息中发送期货是否可以?
示例:actor A发送消息Response to actor B,Response包含其字段中的future.然后在某个时刻A将履行创造未来的承诺.收到响应后,B可以随时调用flatMap()或get().
我问,因为Akka消息应该是不可变的,即使actor在不同的JVM上也能工作.如果演员A和B在不同的JVM上,我看不出上面的例子是如何工作的.此外,即使演员在同一个JVM上,我的示例是否有任何问题?
在此stackoverflow问题中,在接受的答案中完成了类似的操作.如果演员在不同的JVM上,这会起作用吗?
没有遥控它是可能的,但仍然不可取.使用远程处理它根本不起作用.
如果您的目标是Future
使用返回s 的API ,但使用actor作为下面的管道,则一种方法可能是API在内部创建自己的actor ask
,然后将该请求的未来返回给调用者.由API调用生成的actor保证是API实例的本地,并且可以通过常规tell
/ receive
机制与actor系统的其余部分进行通信,因此不会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创建一个内联的actor,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和临时演员之间的共享值,有些人可能会认为这是气味,但应该知道如何实现您的工作流程.