I'm playing with Akka and I have a design in which a supervisor actor has a child playing role A and several children playing role B. I want to define a supervision policy such as A failures are escalated (terminating the supervisor) and B ones produces the individual actors to be restarted.
Is this possible? Is it advisable?
Yes, by overriding supervisorStrategy
. For example, from the docs:
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: ArithmeticException => Resume
case _: NullPointerException => Restart
case _: IllegalArgumentException => Stop
case _: Exception => Escalate
}
Then reading the note:
If the strategy is declared inside the supervising actor (as opposed to within a companion object) its decider has access to all internal state of the actor in a thread-safe fashion, including obtaining a reference to the currently failed child (available as the sender of the failure message).
So rather than matching on the type of the exception, you would match on the sender (just typing here; it might not compile):
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
if (sender == SomeSpecialChild) Escalate
else Restart
}
There's nothing wrong with this, but if you have groups of children playing different roles, you should probably follow the first rule of Akka (well, my first rule of Akka): when in doubt, you probably want another actor. Create one actor to supervise role A and another to supervise role B. You'll still need to override supervisorStrategy
, but the test will be simpler. And it'll be easier to manage any other special differences between role A and B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With