Reputation: 29577
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.
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 the GetBuzzDataCallback
with bData
; orBuzz
throws a BuzzIsAngryException
; orBuzz
throws some other kind of exception/errorI’m wondering what happens with the latter two cases:
GetBuzzDataCallback
sent the exception as its Throwable failure
argument? Or, is the FizzFailureDecider
invoked? Or both (it seems a bit redundant and complicating if both the callback and the decider/supervisor strategy are passed the error)?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)!
Upvotes: 0
Views: 493
Reputation: 11479
What ask does is basically starting a temporary actor that will be the sender of the message so that when the recipient replies it will end up in this temporary actor. The temporary actor creates a Promise
and gives away the Future
for it to the caller. If a reply arrives before the given timeout, the temporary actor completes the Promise
with the successful result.
Supervision always happens in actors, and since ask is implemented using an actor, there isn't anything different about the interaction compared to random other actor sending it the message that could make the supervision work differently.
In your case an exception will bubble up to the parent actor, so that it can supervise the child. Then, unless you somehow send a reply message triggered by this failure, the timeout will hit and the temporary ask
-actor will fail the future with an AskTimeoutException
.
So, as this failure would reach the parent from two ways, it might not generally be a good idea to use the ask pattern with parent to child communication.
Upvotes: 0