2014-03-27 25 views
3

我有以下代码:阿卡OneForOneStrategy不起作用

class A extends Actor with ActorLogging { 
    override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 2) { 
    case _ => log.info("An actor has been killed"); Restart 
    } 

    val b = context.system.actorOf(Props[B], "b") 

    def receive = { 
    case _ => context.system.scheduler.schedule(5 seconds, 5 seconds, b, true) 
    } 
} 

class B extends Actor with ActorLogging { 
    def receive = { case true => self ! Kill } 
} 

在演员A实例self ! Kill后,我没有看到一个消息,“一个演员已被杀死”,并随后调用演员A产生“死信”消息,所以没有重新启动。为什么OneForOneStrategy没有被调用?

奇怪的是,我可以删除整个OneForOneStrategy覆盖,程序行为没有任何变化。

回答

6

val b = context.system.actorOf(Props[B], "b")应改为val b = context.actorOf(Props[B], "b")做出新的演员一个孩子,而不是一个顶级演员。

3

您同时重新启动演员“B”,然后在重新启动时抛出异常。从您的postRestart代码中删除self ! true。否则,你期望会发生什么?您将它发送到无限递归重启循环中。

这里的秩序或行动,你看到来说明吧:

  1. 创建演员 “A”
  2. 创建演员 “B”
  3. 发送true至A
  4. 发送true到B
  5. “B”抛出异常true消息
  6. “A”重新启动“B”
  7. 后重新启动“B”发送自身true
  8. 重复步骤5
+0

好的,但是'maxNrOfRetries = 2'应该是这样吗?我意识到无限循环,但我认为这应该在父母演员'A'重试两次后终止,因为这个选项非常有用。 – Anton

+0

@Anton好吧,如果调用postRestart,这意味着Actor已成功重启。所以重试次数是1. – wheaties

+0

我还是不明白。我看到它的方式应该是这样的:开始 - >失败 - >重启#1 - >失败 - >重启#2 - >失败 - >因为maxNrOfRetries = 2停止。我错过了什么吗? – Anton