我需要捕获一个actor系统关闭事件,以便我可以进行一些自定义清理。
object ChildActor {
class Msg
}
class ChildActor extends Actor {
override def receive: Receive = {
case _ : Msg => throw new OutOfMemoryError("error")
}
}
class ParentActor extends Actor {
override val supervisorStrategy = OneForOneStrategy() {
case _: Error => {
Stop
}
case _: Exception => Stop
}
val child = context.actorOf(Props[ChildActor], "child")
override def receive: Receive = {
case a : Msg => child ! a
}
}
object Test extends App {
val customConf = ConfigFactory.parseString("""
akka {
jvm-exit-on-fatal-error = false
}
""")
val actorSystem = ActorSystem("OOMException", ConfigFactory.load(customConf))
val actor = actorSystem.actorOf(Props[ParentActor], "parentActor")
actor ! new Msg
}
当我运行这个应用程序时,我在控制台中看到以下内容:
Uncaught error from thread [OOMException-akka.actor.default-dispatcher-4]: error, shutting down for ActorSystem[OOMException]
java.lang.OutOfMemoryError: error
at nl.ing.api.contacting.callflow.business.actor.TestMyActor$$anonfun$receive$1.applyOrElse(TestMyActor.scala:26)
at akka.actor.Actor$class.aroundReceive$$$capture(Actor.scala:517)
at akka.actor.Actor$class.aroundReceive(Actor.scala)
at nl.ing.api.contacting.callflow.business.actor.TestMyActor.aroundReceive(TestMyActor.scala:22)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:527)
at akka.actor.ActorCell.invoke(ActorCell.scala:496)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
[ERROR] [SECURITY][04/10/2018 11:34:19.177] [OOMException-akka.actor.default-dispatcher-4] [akka.actor.ActorSystemImpl(OOMException)] Uncaught error from thread [OOMException-akka.actor.default-dispatcher-4]: error, shutting down ActorSystem[OOMException]
java.lang.OutOfMemoryError: error
at nl.ing.api.contacting.callflow.business.actor.TestMyActor$$anonfun$receive$1.applyOrElse(TestMyActor.scala:26)
at akka.actor.Actor$class.aroundReceive$$$capture(Actor.scala:517)
at akka.actor.Actor$class.aroundReceive(Actor.scala)
at nl.ing.api.contacting.callflow.business.actor.TestMyActor.aroundReceive(TestMyActor.scala:22)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:527)
at akka.actor.ActorCell.invoke(ActorCell.scala:496)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
日志显示关闭ActorSystem 。是否有任何方法或回调,我可以用来捕获此关闭并调用自定义清理代码?
当这个致命错误由子actor创建时,则不会调用父监督策略。知道为什么吗?
TIA!
答案 0 :(得分:-1)
这里当一个子actor创建异常时,它必须升级到父actor或者由它监视,以便你可以捕获这个关闭。
对于你的子actor中的覆盖supervisorStrategy。
override val supervisorStrategy = OneForOneStrategy() {
case _: Exception => {
log.info("The exception is Escalating to parent Actor")
Escalate } }
现在它将升级为parentActor并按要求处理。
或者这里为了在子actor终止时通知parentActor可以使用context.watch(child)注册自己接收