我编写了一个测试,以使父演员在子演员上实施了监督策略,如果孩子被杀死然后重新启动孩子,则测试代码中的问题-原因是父演员被终止。 child,现在应该重新启动child,但是重新启动代码无法按预期工作。

@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时,不会引发任何异常。不会调用preRestart中的fundActor钩子,因为fundActor在收到PoisonPill时不会重新启动。

因此,您的测试不会测试监督策略。它正在测试fundActor发送到PoisonPill时是否停止。如果要测试是否重新启动fundActor


fundActor处理一条消息,该消息在收到后会引发RuntimeException
发送此消息而不是PoisonPillfundActor
删除以下行:

advisorrActor.expectTerminated(fundActor);
fundActor发送另一则消息(不会引发异常),并希望得到答复。

07-26 02:46