La stratégie de supervision par défaut est de redémarrer enfant acteur si l'exception est du type Exception
(ou ses enfants).
Lorsque la stratégie de superviseur n'est pas défini pour un acteur les exceptions suivantes sont gérées par défaut:
ActorInitializationException arrêtera l'enfant acteur ne
ActorKilledException arrêtera l'enfant acteur ne
DeathPactException va arrêter l'acteur enfant défaillant
Exception redémarrage t il ne enfant acteur
D'autres types de Throwable sera transmise à l'acteur parent
Alors oui, vous avez besoin d'ajouter une stratégie de surveillance à chaque niveau dans ce cas.
Exemple:
import akka.actor.SupervisorStrategy.{Escalate, Restart, Resume, Stop}
import akka.actor.{Actor, ActorLogging, ActorSystem, OneForOneStrategy, Props}
import scala.concurrent.duration._
class RootActor extends Actor with ActorLogging {
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: Exception => {
log.info("Got exception in root")
Escalate
}
}
override def receive: Receive = {
case "START_ROOT" =>
log.info("Started root actor")
val parentActor = context.actorOf(Props(classOf[ParentActor]))
parentActor ! "START_PARENT"
}
}
class ParentActor extends Actor with ActorLogging {
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: Exception => {
log.info("Got exception in parent")
Escalate
}
}
override def receive: Receive = {
case "START_PARENT" =>
log.info("Started parent actor")
val childActor = context.actorOf(Props(classOf[ChildActor]))
childActor ! "START_CHILD"
}
}
class ChildActor extends Actor with ActorLogging {
override def receive: Receive = {
case "START_CHILD" =>
throw new Exception("Exception from CHILD ACTOR")
log.info("Started child actor")
}
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
log.info("Restarting child actor")
super.preRestart(reason, message)
}
}
object App {
def main(args: Array[String]): Unit = {
val system = ActorSystem("my-system")
val rootActor = system.actorOf(Props(classOf[RootActor]))
rootActor ! "START_ROOT"
}
}
Dans ce cas, exception de l'acteur de l'enfant sera transmise à l'acteur racine.