akka getSender() lost in future

2019-07-17 16:22发布

问题:

I have a problem in akka (java) with the reference of the sender which disappears after a while in a future. Here is the code:

class MyActor extends UntypedActor {
  @Override
  public void onReceive(Object msg){
    Future<Integer> future = Futures.future(new Callable<Integer>(){
      @Override
      public Integer call() throws Exception {
        System.out.println(getSender()); //works fine
        Thread.sleep(1000);
        System.out.println(getSender()); //show deadLetter
        return 42;
      }
    },getContext().dispatcher());

    //do something with the future, pipe it or whatever
    Patterns.pipe(future,getContext().dispatcher(),getSender());
  }
}

I might have missed something in the doc.

回答1:

It is explained in the Actors, section of the docs with a big warning sign:

Warning When using future callbacks, inside actors you need to carefully avoid closing over the containing actor’s reference, i.e. do not call methods or access mutable state on the enclosing actor from within the callback. This would break the actor encapsulation and may introduce synchronization bugs and race conditions because the callback will be scheduled concurrently to the enclosing actor. Unfortunately there is not yet a way to detect these illegal accesses at compile time. See also: Actors and shared mutable state

It is also explained here:

http://doc.akka.io/docs/akka/2.0.2/general/jmm.html#jmm-shared-state

When you close over "getSender()" you're really closing over "this.getSender()", which means that you're closing over the internal state of the actor, which the docs above tells you not to.

I will add this to our FAQ.

Happy hAkking,



标签: java akka future