防止Akka actor重新启动子actor [英] Prevent akka actor from restarting child actor

查看:73
本文介绍了防止Akka actor重新启动子actor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让演员 Worker 不在其重新启动时重新启动其子演员 SubWorker 自己的主管 Mngr 。即使覆盖了 Worker中的 preRestart() postRestart ,我还是失败了。日志仍然显示 SubWorker 直到重新启动。我是Akka和Actor模型的新手,我不知道自己在做错什么。

I'm trying to get an actor Worker to not restart its child actor SubWorker when it's restarted by it's own supervisor Mngr. I've been unsuccessful even after overriding the preRestart() and postRestart in Worker. The logs still show that SubWorker is till being restarted. I'm new to Akka and Actor model, I don't know what I'm doing wrong.

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


推荐答案

Actor重新启动,因为其内部状态已变为无效并且不再受信任。由于它创建的子角色是角色状态的一部分,因此还需要清除它们-通过停止并重新创建(这是默认设置)或依次重新启动。这是无法避免的。如果您有一个应在其他演员B幸存下来的演员A,则A不能是B的子代。因此,在这种情况下,您将需要重组您的监督层次结构。

An Actor is restarted because its internal state has become invalid and cannot be trusted anymore. Since the child actors it creates are part of an actor’s state, they also need to be cleared out—either by stopping and re-creating (which is the default) or by being restarted in turn. This cannot be avoided. If you have an actor A which should survive some other actor B, then A cannot be a child of B. So in this case you will need to restructure your supervision hierarchy.

这篇关于防止Akka actor重新启动子actor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆