java - ChildActor 没有重新启动或没有执行 preRestart() Akka

标签 java akka

我编写了一个测试,这样父 Actor 对子 Actor 实现了监督策略,如果子 Actor 被杀死,则子 Actor 会重新启动,测试代码中的问题 - 失败的原因是父 Actor 被终止。来自子级的类消息,现在应该重新启动子级,但重新启动代码无法按预期工作。

@Test
  public void test_actor_strategy_for_fund_actor() throws InterruptedException {
    JavaTestKit adviserActor = new JavaTestKit(system);
    ActorRef fundActor = adviserActor.childActorOf(Props.create(FundActor.class, () -> new FundActor("fund-actor")),
        new OneForOneStrategy(10, create(10, SECONDS), new Function<Throwable, Directive>() {
          @Override
          public Directive apply(Throwable thrown) {
            if (thrown instanceof RuntimeException)
              return restart();
            return akka.actor.SupervisorStrategy.stop();
          }
        }));
    adviserActor.watch(fundActor);
    fundActor.tell(PoisonPill.getInstance(), adviserActor.getRef());
    adviserActor.expectTerminated(fundActor);
  }

因此,在记录行上方的最后一行代码之后,应在 Actor 的 preRestart() 函数中打印 - 但这不会发生 - 知道为什么吗?

最佳答案

向参与者发送PoisonPill会阻止它并且不会调用其监督策略。当参与者处理消息时抛出异常时,监督策略就会发挥作用;当参与者收到 PoisonPill 时,不会引发异常。不会调用 fundActor 中的 preRestart Hook ,因为 fundActor 在接收到 PoisonPill 时不会重新启动。

因此,您的测试并不测试监督策略;而是测试监督策略。它正在测试当向其发送 PoisonPillfundActor 是否停止。如果你想测试fundActor是否重启:

  • fundActor 处理一条消息,该消息在收到时抛出 RuntimeException
  • 将此消息而不是 PoisonPill 发送给 fundActor
  • 删除以下行:

    adviserActor.expectTerminated(fundActor);
  • fundActor 发送另一条消息(不会引发异常的消息)并期待回复。

关于java - ChildActor 没有重新启动或没有执行 preRestart() Akka,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45634682/

相关文章:

java - 使用 JOOQ 的 MockDataProvider,如何设置返回的 lastId()?

Java 泛型 : Can I Use an Object as a Formal Parameter?

java - 用于在 Java 或 C++ 中生成独立 Windows 可执行文件的库

docker - docker容器内的akka​​应用程序问题

c# - Actor 模型 (Akka.net) 中存储的状态在哪里?

java - Spring/JPA @OneToMany 关系返回一个大小为 0 的列表,而它应该返回更多。为什么?

java - 计算句子,只计算以标点符号+2个空格结尾的句子

java - Akka - 如何告诉系统在达到策略的最大重试次数后做什么?

scala - 如何防止喷涂应用过载?

java - 使用 Akka 持久邮箱进行事务消息处理