杀死父母演员也杀了孩子吗?看到一些不同的行为

时间:2016-10-07 16:58:23

标签: akka

我没有想到,如果你杀死了父母,孩子们也会被杀死,但是当我尝试下面给出的这样的东西时,我会得到不同的行为。有人可以解释一下吗?

1. Here the actor GrandFather creates Son and Son creates GrandSon. 
2. Grandson sends a message to GandFather, so Grandfather gets the actoRef of the Grandson.
3. Then on receiving a specific message ("crash") from GrandFather, Son throws an exception.
4. Now GrandFather tries to send messages to both Son and GrandSon. Messages to Son goes to Deadletter Queue, whild messsages to GrandSon is received and printed.

 object GrandFather{
   def props()=Props(new GrandFather)
 }
 class GrandFather extends Actor with ActorLogging {
   var child:ActorRef=Actor.noSender
   override def receive: Receive = {
     case x:String if x.equals("Test Grandpa") =>
       println("I am grand father ->" + x)
       child = context.actorOf(Son.props)
       child ! "Test Son"
     case y:String =>
      val grandChild = sender()
      println("I am the grandfather, Got Message from grand child, gonna kill my son")
      child ! "crash"
      child ! "there"
      grandChild ! "Are you Alive?"
       child ! "there"
       grandChild ! "Are you Alive?"
       child ! "there"
       grandChild ! "Are you Alive?"
       child ! "there"
       grandChild ! "Are you Alive?"
       child ! "there"
   }
 }

 object Son{
   def props:Props = Props(new Son)
 }
 class Son extends Actor with ActorLogging {
   var actr:ActorRef = Actor.noSender

   def receive:Receive={
     case y:String if y.equals("crash") => throw new Exception("killed by self")
     case z:String if z.equals("there") => println("I am the son -> " + "still here")
     case x:String => {
       val k = sender()
       println("I am the son -> " + x)
       actr = context.actorOf(GrandSon.props())
       actr ! ("Test GrandChild ", k)
     }
   }
 }

 object GrandSon{
   def props() = Props(new GrandSon)
 }
 class GrandSon extends Actor with ActorLogging {
   def receive:Receive={
     case (x:String, y:ActorRef) => {
       println("I am the grand child -> " + x)
       y ! "go ahead and kill your son, i.e. my father"
     }
     case y:String if y.equals("Are you Alive?") => println("I am Grand Child, grandpa I am still alive")
   }
 }

此代码的输出:

 Testing started at 17:57 ...
 I am grand father ->Test Grandpa
 I am the son -> Test Son
 I am the grand child -> Test GrandChild 
 I am the grandfather, Got Message from grand child, gonna kill my son
 I am Grand Child, grandpa I am still alive
 I am Grand Child, grandpa I am still alive
 I am Grand Child, grandpa I am still alive
 I am Grand Child, grandpa I am still alive
 [WARN] [10/07/2016 17:57:10.818] [test-akka.actor.default-dispatcher-3] [akka://test/user/$a/$a] received dead letter from Actor[akka://test/user/$a#-275386619]: there
 [WARN] [10/07/2016 17:57:10.819] [test-akka.actor.default-dispatcher-3] [akka://test/user/$a/$a] received dead letter from Actor[akka://test/user/$a#-275386619]: there
 [WARN] [10/07/2016 17:57:10.820] [test-akka.actor.default-dispatcher-3] [akka://test/user/$a/$a] received dead letter from Actor[akka://test/user/$a#-275386619]: there
 [WARN] [10/07/2016 17:57:10.821] [test-akka.actor.default-dispatcher-3] [akka://test/user/$a/$a] received dead letter from Actor[akka://test/user/$a#-275386619]: there
 [WARN] [10/07/2016 17:57:10.821] [test-akka.actor.default-dispatcher-3] [akka://test/user/$a/$a] received dead letter from Actor[akka://test/user/$a#-275386619]: there

1 个答案:

答案 0 :(得分:2)

每个文档默认策略

ActorInitializationException will stop the failing child actor
ActorKilledException will stop the failing child actor
Exception will restart the failing child actor
Other types of Throwable will be escalated to parent actor

你实际上并没有杀死演员,而是重新启动它。

如果你想证明这一点,请为儿子演员重写更多方法

就像在文档

中一样
def preStart(): Unit = ()

def postStop(): Unit = ()

def preRestart(reason: Throwable, message: Option[Any]): Unit = {
  context.children foreach { child ⇒
    context.unwatch(child)
    context.stop(child)
  }
  postStop()
}

def postRestart(reason: Throwable): Unit = {
  preStart()
}