7

Akka のドキュメントの正しい引用は次のように述べています。

再起動中のイベントの正確なシーケンスは次のとおりです。アクターを一時停止し (再開されるまで通常のメッセージを処理しないことを意味します)、すべての子を再帰的に一時停止します。

誤解を招く引用は次のように述べています。

アクターを再開すると、そのすべての部下が再開されます。アクターを再開すると、すべての部下が再起動されます。同様に、アクターを終了すると、すべての部下も終了します。

親メソッドで子を再帰的かつ明示的に作成しない限りpreStart、Akka の用語RESTARTは reSTART ではないため、メソッドで子 (ren) を作成するのは私たちの責任であると私は考えていますpreStart()

例 (Akka 2.0 および 2.2-SNAPSHOT を使用): このテスト ケースでは、何を試しても、子プロセスは常に停止され、再開されることはありません。Supervisor-> First->の関係を作成Secondし、例外をスローしますSupervisor。何が起こるかというと、再supervisor起動して停止します。FirstSecond

  test("restart test") {
    val system = ActorSystem("test")
    val supervisor = system.actorOf(Props(new Supervisor), "supervisor")
    supervisor ! CREATE(Props(new First), "first")
    Thread.sleep(500)

    val first = system.actorFor("akka://test/user/supervisor/first")
    first ! CREATE(Props(new Second), "second")
    Thread.sleep(500)
    supervisor ! WTF

    Thread.sleep(20000)
  }

  case object WTF
  case class CREATE(p: Props, name: String)

  class Supervisor extends Actor {
    override val supervisorStrategy =
      OneForOneStrategy(maxNrOfRetries = 10) {
        case _: IllegalStateException       => Restart
        case _: IllegalArgumentException    => Stop
        case _: Exception                   => Restart
    }
    override def preStart() {
      println(s"$self starts")
    }
    override def postStop() {
      println(s"$self stopped")
    }
    override def receive = {
      case WTF => println("throwing exception"); throw new IllegalStateException()
      case CREATE(p, name) => context.actorOf(p, name)
    }
  }
  class First extends Actor {
    override def preStart() {
      println(s"$self starts")
    }
    override def postStop() {
      println(s"$self stopped")
    }
    override def receive = {
      case WTF => println("throwing exception"); throw new IllegalStateException()
      case CREATE(p, name) => context.actorOf(p, name)
    }
  }
  class Second extends Actor {
    override def preStart() {
      println(s"$self starts")
    }
    override def postStop() {
      println(s"$self stopped")
    }
    override def receive = {
      case WTF => println("throwing exception"); throw new IllegalStateException()
      case CREATE => sender ! "ok"
    }
  }

アクター[akka://test/user/supervisor#1599926629] 開始 アクター[akka://test/user/supervisor/first#2012011668] 開始 アクター[akka://test/user/supervisor/first/second#1750038710]始まる

スロー例外 Actor[akka://test/user/supervisor#1599926629] 停止 [ERROR] [06/26/2013 11:11:16.899] [test-akka.actor.default-dispatcher-4] [akka:// akka.actor.ActorCell.receiveMessage(ActorCell. scala:498) で akka.actor.ActorCell.invoke(ActorCell.scala:456) で akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237) で akka.dispatch.Mailbox.run(Mailbox.scala:219) でakka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386) で scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262) で scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java: 975) scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478) scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104) で

アクター[akka://test/user/supervisor/first/second#1750038710] 停止 アクター[akka://test/user/supervisor/first#2012011668] 停止 アクター[akka://test/user/supervisor#1599926629]始まる

4

1 に答える 1