Scala 远程参与者使用作业ID和结果进行响应

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

在不同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

更新: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发送延续消息而分块时,这才有效;您显示的未来无法取消。不过,剩下的还是不错的。