Scala akka:未收到终止回调

Scala akka:未收到终止回调,scala,callback,akka,terminate,actorsystem,Scala,Callback,Akka,Terminate,Actorsystem,我有一个actorsystem,在那里我注册了一些actorsystem终止代码。代码如下- object ChildActor { class Msg } class ChildActor extends Actor { val log = Logging(context.system, this) override def receive: Receive = { case a : String => log.info(s"received $a") c

我有一个actorsystem,在那里我注册了一些actorsystem终止代码。代码如下-

object ChildActor {
  class Msg
}

class ChildActor extends Actor {
  val log = Logging(context.system, this)

  override def receive: Receive = {
    case a : String => log.info(s"received $a")
    case _ : Msg => throw new OutOfMemoryError("error")
  }
}

class ParentActor extends Actor {
  override val supervisorStrategy = OneForOneStrategy() {
    case _: OutOfMemoryError => {
      Stop
    }
    case _: Exception => Stop
  }
  val child = context.actorOf(Props[ChildActor], "child")
  override def receive: Receive = {
    case a: String => child ! a
    case msg : Msg => child ! msg
  }
}

object Test extends App {

  val customConf = ConfigFactory.parseString("""
  akka {
    jvm-exit-on-fatal-error = false
  }
  """)


  val actorSystem = ActorSystem("OOMException", ConfigFactory.load(customConf))

  actorSystem.registerOnTermination(println("going off"))

  val actor = actorSystem.actorOf(Props[ParentActor], "parentActor")

  actor ! new Msg

}
我注意到的古怪行为与我的回电有关。当我正常运行应用程序时,我从来没有收到过注册代码的回调

但是,当我在调试模式下运行并在方法中等待几秒钟时,该行就会被打印出来。。我不知道为什么这几秒钟的等待可以确保所有注册的回调都被触发,而在正常运行模式下它不会发生。有人知道吗

注:我知道OOM是致命的,但我只是好奇手头的问题,OOM只是其中一种情况

当我在结尾进行线程转储时,我看到以下两个线程始终存在-

"OOMException-akka.actor.default-dispatcher-2" #12 prio=5 os_prio=0 tid=0x000000001e8dd800 nid=0x1029c waiting on condition [0x0000000020eff000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000770700c90> (a akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinPool)
    at akka.dispatch.forkjoin.ForkJoinPool.scan(ForkJoinPool.java:2075)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

"OOMException-scheduler-1" #11 prio=5 os_prio=0 tid=0x000000001e5d8800 nid=0xfba4 waiting on condition [0x000000001f35e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at akka.actor.LightArrayRevolverScheduler.waitNanos(LightArrayRevolverScheduler.scala:85)
    at akka.actor.LightArrayRevolverScheduler$$anon$4.nextTick(LightArrayRevolverScheduler.scala:265)
    at akka.actor.LightArrayRevolverScheduler$$anon$4.run(LightArrayRevolverScheduler.scala:235)
    at java.lang.Thread.run(Thread.java:748)
“OOMException akka.actor.default-dispatcher-2”#12 prio=5 os_prio=0 tid=0x000000001e8dd800 nid=0x1029c等待条件[0x0000000020eff000]
java.lang.Thread.State:等待(停车)
在sun.misc.Unsafe.park(本机方法)
-停车等待(akka.dispatch.ForkJoinExecutor配置程序$AkkaForkJoinPool)
位于akka.dispatch.forkjoin.ForkJoinPool.scan(ForkJoinPool.java:2075)
位于akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
在akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
“OOMException-scheduler-1”#11优先级=5 os优先级=0 tid=0x000000001e5d8800 nid=0xfba4等待条件[0x000000001f35e000]
java.lang.Thread.State:定时等待(休眠)
位于java.lang.Thread.sleep(本机方法)
在akka.actor.LightArrayRevolverScheduler.waitNanos(LightArrayRevolverScheduler.scala:85)
在akka.actor.LightArrayRevolverScheduler$$anon$4.nextTick(LightArrayRevolverScheduler.scala:265)
在akka.actor.LightArrayRevolverScheduler$$anon$4.run(LightArrayRevolverScheduler.scala:235)
运行(Thread.java:748)

当actor系统终止时,调度程序应该已经完成。不确定为什么会处于定时等待状态。

App
在这里可能很棘手,可能JVM在执行回调之前就终止了(因为剩下的所有线程都是守护进程线程)

我首先建议将应用程序代码放在
defmain(…)
方法中

使用类似于此的内容而不是
println

val promise = Promise.empty[Unit]
actorSystem.registerOnTermination(promise.success(()))
val actor = actorSystem.actorOf(Props[ParentActor], "parentActor")
actor ! new Msg
Await.ready(promise.future, Duration.INF)
println("going off")

似乎与我最初发布的代码没有任何不同。如果您正常终止
ActorSystem
,而不是通过错误,您是否也有相同的问题?