Предотвратить akka actor от перезапуска дочернего актера

Я пытаюсь найти актера Worker не перезапускать своего дочернего актера SubWorker когда он перезапускается своим собственным руководителем Mngr, Я потерпел неудачу даже после переопределения preRestart() а также postRestart в Worker, Логи все еще показывают, что SubWorker до перезапуска. Я новичок в модели Akka и Actor, я не знаю, что я делаю неправильно.

case class Start()
case class ThrowExp()

class Mngr extends Actor {

  val log = Logging(context.system, this)

  override def preStart(): Unit = {
    self ! Start
  }

  def receive: Receive = {

    case Start =>
      context.actorOf(Props[Worker], "myWorker")

    case "walker_throw_exp" =>
      context.child("myWorker").get ! ThrowExp
  }
}

class Worker extends Actor {


  val log = Logging(context.system, this)

  override def preStart(): Unit = {
    self ! Start
  }


  override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
    postStop()
  }


  override def postRestart(reason: Throwable): Unit = { }

  def receive: Receive = {

    case Start =>
      // create sub worker
      context.actorOf(Props[SubWorker], "mySubWorker")


    case ThrowExp => throw new Exception("Some exception")

  }
}

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

  def receive: Receive = {
    case _ => log.info("I'm a sub worker")
  }
}

val system = ActorSystem("MySystem")
import system.dispatcher

val manager = system.actorOf(Props[Mngr], "Manager")
system.scheduler.scheduleOnce(2.seconds, manager, "walker_throw_exp")

Журнал

[DEBUG] [12/11/2013 20:22:04.409] [main] [EventStream(akka://MySystem)] logger log1-Logging$DefaultLogger started
[DEBUG] [12/11/2013 20:22:04.411] [main] [EventStream(akka://MySystem)] Default Loggers started
[DEBUG] [12/11/2013 20:22:04.417] [MySystem-akka.actor.default-dispatcher-4] [akka://MySystem/system] now supervising Actor[akka://MySystem/system/deadLetterListener#-1362953699]
[DEBUG] [12/11/2013 20:22:04.419] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/system/deadLetterListener] started (akka.event.DeadLetterListener@250f4a60)
[DEBUG] [12/11/2013 20:22:04.427] [MySystem-akka.actor.default-dispatcher-3] [akka://MySystem/user] now supervising Actor[akka://MySystem/user/Manager#-684317580]
[DEBUG] [12/11/2013 20:22:04.429] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager] started (com.gangfly.gangbot.Mngr@34b0e482)
[DEBUG] [12/11/2013 20:22:04.431] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager] now supervising Actor[akka://MySystem/user/Manager/myWorker#429127943]
[DEBUG] [12/11/2013 20:22:04.432] [MySystem-akka.actor.default-dispatcher-4] [akka://MySystem/user/Manager/myWorker] started (com.gangfly.gangbot.Worker@7b70a0d3)
[DEBUG] [12/11/2013 20:22:04.434] [MySystem-akka.actor.default-dispatcher-4] [akka://MySystem/user/Manager/myWorker] now supervising Actor[akka://MySystem/user/Manager/myWorker/mySubWorker#2129589969]
[DEBUG] [12/11/2013 20:22:04.435] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager/myWorker/mySubWorker] started (com.gangfly.gangbot.SubWorker@3c2a5fb9)
[ERROR] [12/11/2013 20:22:06.465] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager/myWorker] Some exception
java.lang.Exception: Some exception
    at com.gangfly.gangbot.Worker$$anonfun$receive$2.applyOrElse(Main.scala:57)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
    at akka.actor.ActorCell.invoke(ActorCell.scala:456)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    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)

[DEBUG] [12/11/2013 20:22:06.465] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager/myWorker] restarting
[DEBUG] [12/11/2013 20:22:06.469] [MySystem-akka.actor.default-dispatcher-2] [akka://MySystem/user/Manager/myWorker] restarted
[DEBUG] [12/11/2013 20:22:06.470] [MySystem-akka.actor.default-dispatcher-3] [akka://MySystem/user/Manager/myWorker/mySubWorker] restarting
[DEBUG] [12/11/2013 20:22:06.471] [MySystem-akka.actor.default-dispatcher-3] [akka://MySystem/user/Manager/myWorker/mySubWorker] restarted

1 ответ

Актер перезапускается, потому что его внутреннее состояние стало недействительным и ему больше нельзя доверять. Поскольку дочерние акторы, которые он создает, являются частью состояния актера, их также необходимо очистить - либо путем остановки и повторного создания (что по умолчанию), либо путем перезапуска по очереди. Этого нельзя избежать. Если у вас есть актер A, который должен пережить какого-то другого актера B, то A не может быть потомком B. Так что в этом случае вам нужно будет реструктурировать свою иерархию надзора.

Другие вопросы по тегам