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.
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,
√