儿童演员是否知道他正在恢复?

时间:2013-05-07 16:56:11

标签: akka actor fault-tolerance akka-supervision

想象一个直接的监督层级。孩子死了。父亲决定Restart孩子。当Restart编辑时,postRestart和朋友被召唤,但如果父亲决定恢复孩子怎么办?儿童演员是否知道他正在恢复?顺便说一下。父亲是否可以访问导致他孩子出现异常的消息?

3 个答案:

答案 0 :(得分:6)

简历意味着“没有真正发生,继续”,并且本着这种精神,孩子甚至都不知情。这是一个很少使用的指令。

父母只会自己获得失败(即Throwable),而不是导致问题的信息,因为这会让你把父母和孩子的逻辑纠缠在健康之外。

答案 1 :(得分:1)

术语“恢复”表示继续处理消息,并在文档中的两个位置引用。

第一个用于响应异常状态: 根据akka文档:

 As described in Actor Systems supervision describes a dependency relationship between actors: the supervisor delegates tasks to subordinates and therefore must respond to their failures. When a subordinate detects a failure (i.e. throws an exception), it suspends itself and all its subordinates and sends a message to its supervisor, signaling failureDepending on the nature of the work to be supervised and the nature of the failure, the supervisor has a choice of the following four options:

Resume the subordinate, keeping its accumulated internal state
Restart the subordinate, clearing out its accumulated internal state
Terminate the subordinate permanently
Escalate the failure, thereby failing itself

请注意,RESTART实际上是KILLS的原始actor。这里再次使用术语“恢复”来表示继续处理消息。

根据akka文档。

The precise sequence of events during a restart is the following:

- suspend the actor (which means that it will not process normal messages until resumed), and recursively suspend all children
- call the old instance’s preRestart hook (defaults to sending termination requests to all children and calling postStop)
- wait for all children which were requested to terminate (using context.stop()) during preRestart to actually terminate; this—like all actor operations—is non-blocking, the termination notice from the last killed child will effect the progression to the next step
- create new actor instance by invoking the originally provided factory again
- invoke postRestart on the new instance (which by default also calls preStart)
- send restart request to all children which were not killed in step 3; restarted children will follow the same process recursively, from step 2
- resume the actor

答案 2 :(得分:0)

如果您在主管的supervisorStrategy中正确设置了这种行为,则可以将故障冒泡到主管。一个显示该行为的小例子:

import akka.actor.Actor
import akka.actor.Props
import akka.actor.ActorSystem

object SupervisorTest {
  def main(args: Array[String]) {
    val system = ActorSystem("test")
    val master = system.actorOf(Props[Master], "master")
    master ! "foo"
    Thread.sleep(500)
    val worker = system.actorFor("/user/master/foo")
    worker ! "bar"
  }
}

class Master extends Actor{
  import akka.actor.OneForOneStrategy
  import akka.actor.SupervisorStrategy._
  import scala.concurrent.duration._

  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
      case _: Exception                => Escalate
        Escalate
    }
  override def preRestart(ex:Throwable, msg:Option[Any]) = {
    println("In master restart: " + msg)
  }

  def receive = {
    case msg:String =>
      context.actorOf(Props[Worker], msg)
  }
}

class Worker extends Actor{
  override def preRestart(ex:Throwable, msg:Option[Any]) = {
    println("In worker restart: " + msg)
  }
  def receive = {
    case _ =>
      throw new Exception("error!!")
  }  
}

您可以在Master演员(我的示例中的主管)中看到,我选择Escalate Exception类型的失败。这将导致无法冒泡到preRestart actor中的Master。现在我期待msg param preRestart成为工人演员的原始违规信息,但事实并非如此。我得到的唯一方法就是覆盖儿童演员的preRestart。在我的示例中,您将按顺序看到主管和孩子的打印输出。