The Shape of Async Callback APIs
When we have async callbacks in a Java API, the idiommatic way of writing the interface to register the callback looks like:
Future<Foo> f = asyncEventThing.addListener(new Listener<Foo>() {
public Foo onEvent(Event e) {
return new Foo(e.getSomethingNifty());
}
})
I'd like to propose that we adopt a new idiom, which is to pass an
Executor along with the listener:
Executor myExecutor = Executors.newSingleThreadExecutor();
// ...
Future<Foo> f = asyncEventThing.addListener(new Listener<Foo>() {
public Foo onEvent(Event e) {
return new Foo(e.getSomethingNifty());
}
}, myExecutor);
The main benefit is that you give the caller control over the threading model for the callback. Right now, most libraries either have a separate thread pool for callbacks, or make the callback on the event generator thread. Usually there is nothing but an obscure reference on a wiki to indicate the behavior.