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

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

问题描述

我有一个演员,他在收到消息后,在文件系统中搜索文件并返回文件的完整路径。

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 而不是发件人 。文档说:

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天全站免登陆