Kao
Kao

Reputation: 2272

Sending back to sender, from supervisor, in case of failure

I have an Actor, which acts as a Supervisor, but also needs to "return" data to the caller, wether this is an actor or not shouldn't matter.

I am asking my Supervisor, let's call him SV.

SV Processes the message I send to him, and sends back a response.

val system = ActorSystem("ActorSystem")
val sv = system.actorOf(Props[SV], name = "SV")

sv ? msg

And SV's recieve method looks like this:

def receive = {
    case msg => (someChild ? msg).pipeTo(sender)
    ...
}

This all works jolly fine. The problem is when the child throws an exception, this exception is caught by the supervisor strategy.

override def supervisorStrategy = OneForOneStrategy () {
    case e : Throwable => {
        val newResponse = someNewResponse
        sender ! newResponse
        ...
    }
}

sender is not longer a reference to whoever called SV in the first place, and I can't seem to work out how to send a message back to the askee, and get back to my original flow.

Upvotes: 1

Views: 394

Answers (2)

doorstuck
doorstuck

Reputation: 2308

Are you using the supervisor strategy and exceptions to control the flow or your data? Consider using the type system (Option type or a Failure on the response Future) for "exception" cases in your child actors and handle the response flow without exceptions.

The supervisor strategy is for unhandled exceptions. When an unhandled exception occurs you lose the ability to respond with a message to the sender. Unless you wrap the sender in the unhandled exception like Roland Kuhn suggests.

Let the supervisor strategy instead handle how the actor system should respond to your unhandled exceptions by mapping them to a Directive.

Upvotes: 1

Roland Kuhn
Roland Kuhn

Reputation: 15472

One of the three Actor rules is: “An Actor can send a finite number of messages to other Actors it knows.” The last two words are critical here: if the supervisor has not been introduced to the original sender somehow and the failure (exception) itself does not contain the sender’s reference either, then the supervisor cannot possibly send a message to the sender. Either you catch all exceptions in the child actor, wrap them together with the sender in your own exception type and then rethrow, or the original message needs to travel via the supervisor to the child and back, so that the supervisor can see that a reply is outstanding when a failure occurs.

Upvotes: 3

Related Questions