在Héctor Veiga Ortiz 的Akka Cookbook中,读者被告知
当一个actor抛出异常时,它会向主管发送一条消息,主管通过重新启动该actor来处理故障。它清除了actor的累积状态,并创建了一个新的actor,这意味着,它将最后分配给旧actor的状态的值恢复为preRestart值。
但是,我尝试测试以下代码,这表明作者所说的不是真的。
import akka.actor._
import akka.actor.SupervisorStrategy._
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.pattern.ask
case object Error
case class StopActor(actorRef: ActorRef)
case object Inc
class LifeCycleActor extends Actor {
var sum = 1
override def preRestart(reason: Throwable, message: Option[Any]):Unit =
println(s"sum in preRestart is $sum")
override def preStart(): Unit = println(s"sum in preStart is $sum")
def receive = {
case Inc => sum += 1
case Error => throw new ArithmeticException()
case _ => println("default msg")
}
override def postStop(): Unit =
println(s"sum in postStop is ${sum * 3}")
override def postRestart(reason: Throwable): Unit = {
sum = sum * 2
println(s"sum in postRestart is $sum")
}
}
class Supervisor extends Actor {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute){
case _: ArithmeticException => Restart
case t =>
super.supervisorStrategy.decider.applyOrElse(t, (_:Any)=>Escalate)
}
def receive = {
case (props: Props, name: String) => sender ! context.actorOf(props, name)
case StopActor(actorRef) => context.stop(actorRef)
}
}
object ActorLifeCycle extends App {
implicit val timeout = Timeout(2 seconds)
val actorSystem = ActorSystem("Supervision")
val supervisor = actorSystem.actorOf(Props[Supervisor], "supervisor")
val childFuture = supervisor ? (Props(new LifeCycleActor), "LifeCycleActor")
val child = Await.result(childFuture.mapTo[ActorRef], 2 seconds)
child ! Inc
child ! Error
Thread.sleep(1000)
supervisor ! StopActor(child)
}
我得到的输出如下。
sbt:chpt2_ActorLifeCycle> runMain ActorLifeCycle preStart
中的总和是 1 preRestart 中的
总和是 2
[错误] [11/08/2018 20:06:01.423] [Supervision-akka.actor.default-dispatcher-4] [akka://Supervision /user/supervisor/LifeCycleActor] null
java.lang.ArithmeticException postRestart 中的总和
为 2 postStop 中的
总和为 6
如果作者所说的是真的,那么最终的价值应该是它的两倍。