FastTracks / TheAkkaWay

Akka Chinese Book / What should be included in it?
Apache License 2.0
19 stars 3 forks source link

sender在Future回调中会变成dead-letters? #34

Open PipsqueakH opened 7 years ago

PipsqueakH commented 7 years ago

考虑这样一个Receive方法

def f: Future[_]

def receive: Receive = {
  case Msg =>
    println("sender is " + sender)
    f onComplete{
    case Success(_) => println("sender is " + sender)
    case Failure(_) => _
    }
}

我用

class MarketTester extends TestKit(ActorSystem("testsystem")) with ImplicitSender

来测试

结果是 sender is Actor[akka://testsystem/system/testActor-1#-2094005222] sender is Actor[akka://testsystem/deadLetters] 这说明TestActor变成了deadLetters。 文档里有 If invoked from an instance that is not an Actor the sender will be deadLetters actor reference by default. 难道在Future的回调中, 当前instance就不是自己的Actor了吗?

另外,最重要的问题是,我在Future的onComplete中如何引用sender?

He-Pin commented 7 years ago

@PipsqueakH 这个是很常见的一个陷阱。

因为 sender() 或者getSender()方法实际上是从现场上下文中拿到原始的 发送者的,当您在使用 Future 的 回调函数时,其具体的执行实际上可能发生在别的线程,如这里,所以就拿不到了。

如果要通过如上的方式使用,请在最开始使用

val originalSender = sender();

将其保存下来,并在 onComplete回调函数中使用。