我有一个简单的actor层次结构,如下所示:
root
|
-- parent1
| |
| -- child1_1
| |
| -- child1_2
|
-- parent2
|
-- child2_1
|
-- child2_2
root
实现supervisorStrategy
处理各种例外情况
如果在parent1
或parent2
中发生未处理的异常,则会到达supervisorStrategy
并正确处理。
如果在任何一个孩子中发生未处理的异常,那么我只是得到[ERROR] akka.actor.OneForOneStrategy
并且就是这样。
如何在层次结构中获取任何未处理的错误以向上传播并到达处理它的root
?
我是否需要处理监督并在每个级别添加Escalate
?
答案 0 :(得分:1)
如果异常的类型为Exception
(或其子代),则默认监督策略是重新启动子actor。
如果没有为参与者定义超级用户策略,则默认情况下会处理以下异常:
ActorInitializationException将停止失败的子actor
ActorKilledException将停止失败的子actor
DeathPactException将停止失败的子actor
例外情况 重启失败的子actor
其他类型的Throwable将升级为父actor
所以是的,在这种情况下,您需要为每个级别添加监督策略。
示例:
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"
}
}
在这种情况下,来自子actor的异常将升级为root actor。