2017-08-11 86 views
0

我已經寫了一個測試,以便父Actor已經對子actor執行監督策略,如果孩子被殺死然後孩子重新啓動,測試代碼中的問題 - 因爲它的失敗是父代actor從孩子終止.class消息,現在孩子應重新啓動,但重啓代碼不能按預期工作。ChildActor沒有得到重新啓動或沒有執行preRestart()Akka

@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); 
    } 

這樣的記錄線以上代碼的最後一行後應打印在演員的preRestart()函數 - 但是,這並不發生 - 任何想法,爲什麼?

+0

第一個猜測,不知道你的代碼的其餘部分:該PoisonPill不會導致兒童演員一個RuntimeException - > SupervisorStrategy.stop()被返回重啓,而不是() – thwiegan

回答

2

發送一個PoisonPill給演員停止它並且不會調用它的監督策略。監督策略在演員處理信息時拋出異常時發揮作用;當演員收到PoisonPill時不會引發異常。 fundActor中的preRestart掛鉤未被調用,因爲fundActor在收到PoisonPill時未重新啓動。

因此,您的測試不會測試監督策略;它正在測試當PoisonPill發送給它時是否停止fundActor。如果你想測試fundActor是否重啓:

  • fundActor處理消息,收到時,拋出一個RuntimeException
  • 發送此消息,而不是PoisonPill,至fundActor
  • 刪除以下行:

    adviserActor.expectTerminated(fundActor);
  • 發送另一個消息(一個不拋出異常),以fundActor和期待答覆。