【发布时间】:2013-06-23 06:03:55
【问题描述】:
Akka 的文档正确引用说:
重新启动期间的确切事件顺序如下: 暂停actor(这意味着它不会正常处理 消息直到恢复),并递归挂起所有子节点。
一个误导性的引用说:
恢复一个actor会恢复它的所有下属,重启一个actor 需要重新启动其所有下属,同样终止一个actor也会终止其所有下属
我怀疑在 preStart 方法中创建子项是我们的责任,因为 Akka 的术语 RESTART 不是 reSTART 除非您在其父项 @ 中递归且显式地创建子项987654322@方法。
示例(使用 Akka 2.0 和 2.2-SNAPSHOT):无论我尝试什么,在这个测试用例中,孩子总是只是停止,从未重新启动。我创建Supervisor -> First -> Second 关系并在Supervisor 中抛出异常。发生的情况是supervisor 重新启动,First & Second 停止。
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] 开始 Actor[akka://test/user/supervisor/first#2012011668] 开始 Actor[akka://test/user/supervisor/first/second#1750038710] 开始
抛出异常 Actor[akka://test/user/supervisor#1599926629] 停止 [错误] [06/26/2013 11:11:16.899] [test-akka.actor.default-dispatcher-4] [akka://test/user/supervisor] null java.lang.IllegalStateException 在 com.fg.mail.smtp.IntegrationSuite$Supervisor$$anonfun$receive$1.applyOrElse(IntegrationSuite.scala:40) 在 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] 停止 Actor[akka://test/user/supervisor#1599926629] 开始
【问题讨论】: