Scala 远程参与者使用作业ID和结果进行响应
在不同JVM上的远程Akka参与者之间通过消息发送未来是否安全/可行?我想不是。因此,我如何才能实现以下目标。关键的方面是尝试让应答(Ack)返回未来的结果,以及允许取消的引用Scala 远程参与者使用作业ID和结果进行响应,scala,akka,Scala,Akka,在不同JVM上的远程Akka参与者之间通过消息发送未来是否安全/可行?我想不是。因此,我如何才能实现以下目标。关键的方面是尝试让应答(Ack)返回未来的结果,以及允许取消的引用 case class BigJob() case class Ack(jobId: Long, result: Future[Int]) case class Cancel(jobID: Long) val ack = (remoteActor ? BigJob()).mapTo[Ack] if(changedMyM
case class BigJob()
case class Ack(jobId: Long, result: Future[Int])
case class Cancel(jobID: Long)
val ack = (remoteActor ? BigJob()).mapTo[Ack]
if(changedMyMind) remoteActor ! Cancel(ack.jobID)
else ack.result foreach println
更新:Am使用Scala 2.10.1和Akka 2.1.2对于远程参与者,您可以使用其他等待参与者:
var myActor = actor {
var waitingSender: Option[OutputChannel[Any]] = None
var result: Option[BigJobResult] = None
val jobID = remoteActor !? StartBigJob() match { case l: Long => l }
loop {
react {
case "stop" =>
remoteActor ! Cancel(jobID)
exit
case "getResult" => result match {
case Some(r) =>
sender ! r
exit
case None => waitingSender = Some(sender)
}
case r: BigJobResult => waitingSender match {
case Some(s) =>
s ! r
exit
case None => result = Some(BigJobResult)
}
}
}
}.start
if(changedMyMind) myActor ! "stop"
else myActor !? "getResult" ...
更新:使用akka
case object ChangedMyMind
case object GetResult
case object BigJob
case class BigJobResult(i: Int)
case class Cancel(jobId: Long)
case class JobStarted(jobId: Long)
val remoteActor = actor( new Act {
become {
case c: Cancel => println(c); context.stop(self)
case BigJob =>
val target = sender
sender ! JobStarted(666)
Future{ Thread.sleep(10000); target ! BigJobResult(13) }
}
})
val a = actor(new ActWithStash {
whenStarting { remoteActor ! BigJob }
become {
case JobStarted(jobId) => unstashAll(); becomeStacked {
case ChangedMyMind => remoteActor ! Cancel(jobId); context.stop(self)
case r: BigJobResult => unstashAll(); becomeStacked {
case GetResult => sender ! r; context.stop(self)
case ChangedMyMind => context.stop(self)
}
case GetResult => stash()
}
case ChangedMyMind | BigJobResult(_) | GetResult => stash()
}
})
if(changedMyMind) a ! ChangedMyMind
else (a ? GetResult) foreach println
谢谢,我想这是在使用Scala演员。我会努力理解其本质,看看额外的演员技巧是否能解决我的取消需求。为了清楚起见,请更新我的问题。@Pengin:它们非常相似?更新。我想我现在明白了,多亏了你的例子,我学到了堆叠行为。所以,我可以用一个中间演员。如果A是呼叫参与者,B是中间人,C是远程“工作人员”,那么…A启动B并可以使用ask发送作业,从而为结果返回未来。B将请求发送到C,并返回作业ID以取消。A可以与B一起发起取消,或者只是等待结果返回。很棒的东西。@Pengin:小心
ActWithStash
。在消息中发送未来很可能是线程安全的,但它在远程处理中永远不会起作用:当原始消息被发送时,反序列化的未来将不会完成。请从你的答案中删除前五段,因为它们确实具有误导性。关于BigJob的取消:只有当作业处理通过向self发送延续消息而分块时,这才有效;您显示的未来无法取消。不过,剩下的还是不错的。