Akka Java here. I just read the Akka docs on the “ask” pattern using futures and am not understanding how several things work, with respect to scenarios when both supervisor strategies (deciders) and failure callbacks are part of the picture.
Parent asking a Child
Say I have two actors, Fizz
and Buzz
, where Fizz
is the parent/creator of Buzz
. Because Fizz
is Buzz
’s parent, it has a SupervisorStrategy
for Buzz
that handles its failures:
// Groovy pseudo-code
class Fizz extends UntypedActor {
ActorRef buzz
// Contstructor omitted for brevity, but Buzz is the child of
// Fizz.
@Override
void onReceive(Object message) {
if(message instanceof FizzRequest) {
FizzRequest fReq = message as FizzRequest
// Exceptions thrown here (inside of Buzz) will be
// handled by Fizz’s supervisor strategy.
Future<BuzzData> bDataFut = Patterns.ask(buzz,
fReq.buzzRequest, 500)
bDataFut.onComplete(new GetBuzzDataCallback())
// etc.
} else {
unhandled(message)
}
}
@Override
SupervisorStrategy supervisorStrategy() {
new FizzSupervisorStrategy()
}
}
class Buzz extends UntypedActor {
// …etc.
}
class FizzDecider extends Function<Throwable,Directive> {
@Override
Directive apply(Throwable throwable) {
if(throwable instanceof BuzzIsAngryException) {
return SupervisorStrategy.restart()
}
SupervisorStrategy.stop()
}
}
class FizzSupervisorStrategy extends OneForOneStrategy {
FizzSupervisorStrategy() {
super(true, new FizzDecider())
}
}
class GetBuzzDataCallback extends OnComplete<BuzzData> {
@Override
void onComplete(Throwable failure, BuzzData bData) {
if(failure != null) {
// If Buzz is the child of Fizz, does this code execute, or
// just the FizzDecider above? Or both? I’m so confused!
} else {
// Handle success. Likely use an ‘Inbox’ to send
// ‘bData’ back to Fizz.
}
}
}
Sometimes, Fizz
needs to ask Buzz
for some data. When this happens, there can be one of three results:
Buzz
returns successfully and provides theGetBuzzDataCallback
withbData
; orBuzz
throws aBuzzIsAngryException
; orBuzz
throws some other kind of exception/error
I’m wondering what happens with the latter two cases:
- Who is notified of the exception, in what order, and how? In other words, is the
GetBuzzDataCallback
sent the exception as itsThrowable failure
argument? Or, is theFizzFailureDecider
invoked? Or both (it seems a bit redundant and complicating if both the callback and the decider/supervisor strategy are passed the error)?
Parent asking a non-Child
Same scenario as above, except now Fizz
is not the parent/creator of Buzz
. In this case, can I just assume that the GetBuzzDataCallback
is sent the exception (as its Throwable failure
argument)?
I guess at the root of my question(s) is this: when a supervisor strategy and a future callback are involved, who gets notified when a child exception is thrown, and in what order? As I mentioned above, to me it would be extra confusing if both receive the failure/exception because then you might have a supervisor strategy trying to restart a Buzz
while the callback is trying to do something else (possibly conflicting) with the exception.
Please note: Although certainly not a requirement, I would greatly appreciate it if any code snippets provided be in Java and not Scala (Scala looks like hieroglyphics to me)!