我编写了一个测试,以使父演员在子演员上实施了监督策略,如果孩子被杀死然后重新启动孩子,则测试代码中的问题-原因是父演员被终止。 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
。
发送此消息而不是PoisonPill
到fundActor
。
删除以下行:
advisorrActor.expectTerminated(fundActor);
向fundActor
发送另一则消息(不会引发异常),并希望得到答复。