未来的发件人 [英] sender inside a future

查看:31
本文介绍了未来的发件人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角色,它在接收到消息时,在文件系统中搜索文件并返回文件的完整路径.

I have an actor which on receiving a message, searches the filesystem for a file and returns the full path of the File.

为了保持异步,我做了:

To keep it asynchronous, I have done:

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.文档说:

But I have observed that it returns the message to akka://FileSystem/deadLetters and not the sender. Documentation says that:

仅在 Actor 本身内有效,因此请勿将其关闭并* 发布到其他线程!

Only valid within the Actor itself, so do not close over it and * publish it to other threads!

这是否意味着我必须保持同步?有没有其他办法?

So does it mean, I will have to necessarily keep it synchronous? Is there any other way?

推荐答案

您犯了一个非常常见的错误,即关闭可变状态".您传递给 onComplete 的闭包不会复制 this.sender,因此当您的 onComplete 被调用时,您将消息发送到无论 this.sender 在那个时候指向什么,而不是在你创建闭包时它指向什么.

You are making a very common mistake of "closing over mutable state". The closure you pass to onComplete does not make a copy of this.sender, so when your onComplete gets called, you are sending the message to whatever this.sender happens to point to at that time, not what it pointed to when you created the closure.

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

You can avoid this problem by creating your own local, immutable copy of the current contents of this.sender, and reference that value in the closure:

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

这篇关于未来的发件人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆