akka 2.3.13です。
preStartの中で例外が出た時にpostStopが呼ばれないような挙動があり、微妙に問題になったので本当に呼ばれてないのかどうか調べてみました。
import akka.actor._ object Main extends App { val system = ActorSystem() try { val actor = system.actorOf(Props[SupervisorExceptionActor]) Thread.sleep(3000) (1 to 5).foreach{ actor ! _} } finally { system.shutdown() } } class SupervisorExceptionActor extends Actor { val actor = context.actorOf(Props[ExceptionActor]) override def preStart() = { super.preStart() println(s"preStart() in ${getClass()}") } override def postStop() = { super.postStop() println(s"postStop() in ${getClass()}") } override val supervisorStrategy = OneForOneStrategy(){ case _ => SupervisorStrategy.Stop } def receive = { case x:Terminated => println(s"Terminated ${x}") case x => actor ! x } } class ExceptionActor extends Actor { override def preStart() = { println(s"preStart() in ${getClass()}") // throw new RuntimeException("preStartで死亡") } override def postStop() = println(s"postStop() in ${getClass()}") def receive = { case x: Int if x == 3 => throw new RuntimeException("Receiveで死亡") case x: Int => println(x + " : " + this) } }
preStartの例外をコメントアウトしてreceiveで例外を発生させたときのログ(ExceptionActorのpostStopが呼ばれる)
> run [info] Running Main preStart() in class SupervisorExceptionActor preStart() in class ExceptionActor 1 : ExceptionActor@4f340570 2 : ExceptionActor@4f340570 [ERROR] [02/01/2016 16:12:23.580] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Receiveで死亡 java.lang.RuntimeException: Receiveで死亡 at ExceptionActor$$anonfun$receive$2.applyOrElse(Main.scala:44) at akka.actor.Actor$class.aroundReceive(Actor.scala:467) at ExceptionActor.aroundReceive(Main.scala:36) at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) at akka.actor.ActorCell.invoke(ActorCell.scala:487) at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238) at akka.dispatch.Mailbox.run(Mailbox.scala:220) at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) postStop() in class ExceptionActor [INFO] [02/01/2016 16:12:23.584] [default-akka.actor.default-dispatcher-3] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#1727329357] to Actor[akka://default/user/$a/$a#-526916506] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. [INFO] [02/01/2016 16:12:23.584] [default-akka.actor.default-dispatcher-3] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#1727329357] to Actor[akka://default/user/$a/$a#-526916506] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. postStop() in class SupervisorExceptionActor [success] Total time: 3 s, completed 2016/02/01 16:12:23
preStartで例外を発生させたときのログ(ExceptionActorのpostStopが呼ばれない)
> run [info] Running Main preStart() in class ExceptionActor preStart() in class SupervisorExceptionActor [ERROR] [02/01/2016 16:11:52.124] [default-akka.actor.default-dispatcher-4] [akka://default/user/$a/$a] preStartで死亡 akka.actor.ActorInitializationException: exception during creation at akka.actor.ActorInitializationException$.apply(Actor.scala:166) at akka.actor.ActorCell.create(ActorCell.scala:596) at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:456) at akka.actor.ActorCell.systemInvoke(ActorCell.scala:478) at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:263) at akka.dispatch.Mailbox.run(Mailbox.scala:219) at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) Caused by: java.lang.RuntimeException: preStartで死亡 at ExceptionActor.preStart(Main.scala:39) at ExceptionActor.preStart(Main.scala:36) at akka.actor.Actor$class.aroundPreStart(Actor.scala:472) at ExceptionActor.aroundPreStart(Main.scala:36) at akka.actor.ActorCell.create(ActorCell.scala:580) ... 9 more [INFO] [02/01/2016 16:11:55.125] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#-1647396111] to Actor[akka://default/user/$a/$a#-198589273] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. [INFO] [02/01/2016 16:11:55.125] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#-1647396111] to Actor[akka://default/user/$a/$a#-198589273] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. [INFO] [02/01/2016 16:11:55.125] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#-1647396111] to Actor[akka://default/user/$a/$a#-198589273] was not delivered. [3] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. postStop() in class SupervisorExceptionActor [INFO] [02/01/2016 16:11:55.126] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#-1647396111] to Actor[akka://default/user/$a/$a#-198589273] was not delivered. [4] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. [INFO] [02/01/2016 16:11:55.126] [default-akka.actor.default-dispatcher-2] [akka://default/user/$a/$a] Message [java.lang.Integer] from Actor[akka://default/user/$a#-1647396111] to Actor[akka://default/user/$a/$a#-198589273] was not delivered. [5] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
まあpreStartでエラーでるとActorとしてstartしてなさそうなので気持ちは分かる気がします(;´Д`) 何か呼ばせる方法はあるのかもしれませんが、少なくともこのコードでは呼ばれないというようです。 akka難しい・・・