2017-08-11 1 views
0

J'ai écrit un test tel que l'acteur parent a implémenté une stratégie de supervision sur l'acteur enfant si l'enfant est tué alors que l'enfant est redémarré, le problème dans le code de test - la raison de l'échec est que l'acteur parent reçoit un message terminated.class de l'enfant et que l'enfant doit maintenant être redémarré, mais le code de redémarrage ne fonctionne pas comme prévu.ChildActor ne redémarre pas ou n'exécute pas 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); 
    } 

donc après la dernière ligne de code ci-dessus une ligne connecté doit être imprimé dans la fonction preRestart() de l'acteur - mais qui ne se produit pas - toute idée pourquoi?

+0

guess D'abord, sans connaître le reste de votre code: Le PoisonPill ne provoque pas de RuntimeException dans l'acteur de l'enfant -> SupervisorStrategy.stop() est en cours de retour au lieu de redémarrage() – thwiegan

Répondre

2

L'envoi d'un PoisonPill à un acteur l'arrête et n'appelle pas sa stratégie de supervision. Une stratégie de supervision entre en jeu lorsqu'une exception est levée lorsqu'un acteur traite un message; aucune exception n'est levée lorsqu'un acteur reçoit un PoisonPill. Le preRestart crochet dans fundActor n'est pas appelé, car fundActor n'est pas redémarré lorsqu'il reçoit un PoisonPill. Par conséquent, votre test ne teste pas la stratégie de supervision; Il teste si fundActor est arrêté lorsqu'un PoisonPill lui est envoyé. Si vous voulez tester si fundActor est redémarrés:

  • Avez fundActor gérer un message qui, lors de la réception, jette un RuntimeException.
  • Envoyez ce message, au lieu d'un PoisonPill, à fundActor.
  • Supprimez la ligne suivante:

    adviserActor.expectTerminated(fundActor);
  • Envoyer un autre message (celui qui ne jette pas une exception) à fundActor et attendre une réponse.