Akka:接收关于演员系统关闭的回电

时间:2018-04-10 09:42:48

标签: scala event-handling akka actor

我需要捕获一个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!

1 个答案:

答案 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)注册自己接收