发件人在未来

时间:2013-06-03 13:38:58

标签: scala akka

我有一个接收消息的actor,在文件系统中搜索文件并返回文件的完整路径。

为了保持异步,我做了:

def receive = {
  case s:String => {

    val f = future{
      val ans = search(s)
      println("Input Request: "+s+" output:"+ans+" "+sender.path)
    }
    f.onComplete{
      case Success(x) => sender ! x
      case Failure(y) => println("Could not complete it")
    }
  } 
}

但我发现它将消息返回akka://FileSystem/deadLetters而不是sender。文档说:

  

仅在Actor本身内有效,所以不要关闭它      *将其发布到其他线程!

这是否意味着,我必须保持同步?还有其他方法吗?

3 个答案:

答案 0 :(得分:44)

你正在犯一个“关闭可变状态”的错误。您传递给onComplete的关闭不会复制this.sender,因此当您onComplete被调用时,您正在将消息发送到指向的this.sender {}}那个时候,而不是你创建闭包时指出的那个。

您可以通过创建自己的this.sender当前内容的本地不可变副本来避免此问题,并在闭包中引用该值:

val origSender = sender
f.onComplete {
    case Successs(x) => origSender ! x
    ...
}

答案 1 :(得分:4)

import akka.pattern.pipe

诀窍。这样做的:

val reply = sender
future {
  val ans = searchAndCache(s)
  println("Input Request: "+s+" output:"+ans+" "+reply.path)
  ans
} pipeTo reply

回复发件人

答案 2 :(得分:0)

我知道这已经过时了,但我必须补充一点,
pipeTo 是正确的方法,但您无需复制发件人
你已经在同一个环境中了 实际上管道是为你做的。
它将采用当前发送者引用(通过传递给它的参数)
并用它来为你解决未来(看看它的实施)
只是做:

future {
  val ans = searchAndCache(s)
  println("Input Request: "+s+" output:"+ans+" "+reply.path)
  ans
} pipeTo reply