1

假设我有一个演员一次向其演员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”的方法吗?

(将应用 Java over Scala 示例)

谢谢。

4

2 回答 2

1

当孩子完成处理当前消息时,它会通知父母,它会反过来向孩子发送一条新消息......

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

您当前的主管策略执行以下操作:如果将 aNullPointerException扔给孩子,则孩子会恢复,就好像什么都没发生一样。如果抛出不同的异常,它会在actor层次结构中升级,这可能意味着默认的主管策略启动,在这种情况下,子进程会重新启动。如果您希望孩子不管异常情况如何恢复,请将您的策略​​更改为以下(我使用的是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;
}

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

孩子发生了什么事,父母的触发因素是什么?

我需要覆盖类似“onChileError”的方法吗?

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

于 2017-08-21T20:26:32.013 回答
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(...)

一旦您开始在集群中扩展参与者,这也将有所帮助,因为当节点在集群中变得无法访问时,它不会触发监督策略,只会触发远程死亡监视。

于 2017-08-21T19:23:03.723 回答