我编写了一个测试,这样父 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
时不会重新启动。
因此,您的测试并不测试监督策略;而是测试监督策略。它正在测试当向其发送 PoisonPill
时 fundActor
是否停止。如果你想测试fundActor
是否重启:
- 让
fundActor
处理一条消息,该消息在收到时抛出RuntimeException
。 - 将此消息而不是
PoisonPill
发送给fundActor
。 删除以下行:
adviserActor.expectTerminated(fundActor);
向
fundActor
发送另一条消息(不会引发异常的消息)并期待回复。
关于java - ChildActor 没有重新启动或没有执行 preRestart() Akka,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45634682/