Akka - 在孩子有异常后,父母如何向孩子发送消息

时间:2017-08-17 09:48:48

标签: java akka akka-supervision

假设我有一个parent演员,一次向其child演员发送一条消息

当孩子完成当前消息的处理后,它会通知父母,在其中转向将向孩子发送新消息。

为了保持这个循环,即使孩子在某个消息上崩溃,我也向父母添加了一个SupervisorStrategy:

    private static SupervisorStrategy strategy =
        new OneForOneStrategy(10, Duration.create("1 minute"),
                new Function<Throwable, SupervisorStrategy.Directive>() {
                    @Override
                    public SupervisorStrategy.Directive apply(Throwable t) {
                        if (t instanceof NullPointerException) {
                            return resume();
                        } else {
                            return escalate();
                        }
                    }
                });

这个想法是,无论对孩子说什么,它都将恢复,父母将能够发送下一条消息。

但是父母如何知道错误何时发生,以便发送下一条消息?

父母触发孩子的事情是什么?

我是否需要覆盖“onChileError”方法?

(将通过Scala示例来表示Java)

感谢。

2 个答案:

答案 0 :(得分:1)

  

当孩子完成当前消息的处理后,它会通知父母,在其中转向将向孩子发送新消息....

     

这个想法是,无论对孩子说什么,它都将恢复,父母将能够发送下一条消息。

您当前的主管策略执行以下操作:如果孩子被抛出NullPointerException,孩子就会恢复,好像什么都没发生一样。如果抛出不同的异常,它会逐渐升级到actor层次结构,这可能意味着default supervisor strategy启动,在这种情况下,子进程重新启动。如果您希望孩子在不考虑异常的情况下恢复,请将您的策略​​更改为以下内容(我使用DeciderBuilder):

private static SupervisorStrategy strategy =
  new OneForOneStrategy(10, Duration.create(1, TimeUnit.MINUTES), DeciderBuilder.
    match(Exception.class, e -> {
      // getSelf() is the parent and getSender() is the child
      GiveMeAnotherMessage message = // ...
      getSelf().tell(message, getSender());
      resume();
    })
    .matchAny(o -> escalate())
    .build());

@Override
public SupervisorStrategy supervisorStrategy() {
  return strategy;
}
  

但是父母如何知道错误何时发生,以便发送下一条消息?

     

父母触发孩子的事情是什么?

     

是否有类似&#34; onChileError&#34;我需要覆盖的方法?

决策者可以通过getSender()访问当前失败的孩子的引用,因此您所要做的就是向父母发送一条消息,让其知道孩子已准备好处理另一条消息来自策略本身,如上面的代码所示。

答案 1 :(得分:0)

我建议实现下一个场景(样本在Scala中):

配置管理员策略以阻止错误

// Stop actors on error - DeathWatch will handle restart sequence
override def supervisorStrategy: SupervisorStrategy = SupervisorStrategy.stoppingStrategy

订阅儿童的创造死亡观察

def createWorker() = {
  val worker = actorOf(...)
  context.watch(worker)
  worker
}

如果孩子意外终止,请创建一个新孩子并重新发送要做的当前工作部分(或适当的下一个工作)

case Terminated(actor) => 
  val worker = createWorker()
  worker ! DoWork(...)

一旦你开始在群集中扩展角色,这也会有所帮助,因为当一个节点在群集中无法访问时,它不会触发监督策略,只会远程监视死亡。