0

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

4

1 回答 1

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
于 2013-04-03T10:47:25.713 回答