在不同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(changedMyMind) remoteActor ! Cancel(ack.jobID)
else ack.result foreach println
更新:使用Scala 2.10.1和Akka 2.1.2
答案 0 :(得分:1)
对于远程演员,你可以使用额外的等待演员:
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