2013-12-11 125 views
3

我试图让演员Worker在其自己的导师Mngr重新启动时,不重新启动其子演员SubWorker。即使在覆盖和postRestartWorker之后,我仍然没有成功。日志仍显示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 ([email protected]) 
[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 ([email protected]) 
[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 ([email protected]) 
[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 ([email protected]) 
[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 

回答

4

的演员重新启动,因为它的内部状态已经失效,不能再被信任。由于它创建的孩子演员是演员状态的一部分,他们也需要清除 - 通过停止和重新创建(这是默认设置)或通过轮流重新启动。这是无法避免的。如果你有一个演员A能够存活其他演员B,那么A不能是B的孩子。所以在这种情况下,你将需要重构你的监督层次结构。

+0

感谢您的回答。在什么情况下可以使用preRestart和postRestart方法。我认为我可以重写重新启动的actor的生命周期方法,防止重新启动actor下的方法。 – Kennedy

+0

不,通过这些挂钩,演员可以对它正在重新启动的事实作出反应,例如通过关闭和重新打开数据库连接。重新启动角色的语义由模型定义;最简单的方法是,如果您参加了[反应式编程](https://www.coursera.org/course/reactive)Coursera课程并在第6周专门查看。 –

+0

好的,谢谢 – Kennedy