Search code examples
javaakkaactorakka-supervision

Akka: Custom akka supervision strategies not registered using Java


I am going to explore Akka life cycle and Akka actors supervision strategies. I am creating my own exceptions and override public SupervisorStrategy supervisorStrategy() method for exploring the life-cycle of akka and their recovery strategies. Following is my code:

public class JavaActor extends AbstractActor {

@Override
public PartialFunction<Object, BoxedUnit> receive() {
    System.out.println("----   In the receive method "+Thread.currentThread().getName());
    return ReceiveBuilder.
            matchEquals("Ping" , s -> {
                System.out.println("$$$ Ping Match Successfully");
                throw new EsclateException("Might be esclate");
            }).
            matchAny(x -> {
                System.out.println("### Matched value is :  "+ x);
                sender().tell(new Status.Failure(new Exception("unknown message")), self());
            }).build();
}

@Override
public void preRestart(Throwable reason, Option<Object> message) throws Exception {
    super.preRestart(reason, message);
    System.out.println(">>> Actor preRestart method calls : "+Thread.currentThread().getName());
}

@Override
public void postRestart(Throwable reason) throws Exception {
    super.postRestart(reason);
    System.out.println(">>> Actor postRestart method calls : "+Thread.currentThread().getName());
}

@Override
public void preStart() throws Exception {
    super.preStart();
    System.out.println(">>> Actor preStart method calls "+Thread.currentThread().getName());
}

@Override
public void postStop() throws Exception {
    super.postStop();
    System.out.println(">>> Actor postStop method calls "+Thread.currentThread().getName());
}

@Override
public SupervisorStrategy supervisorStrategy() {
    System.out.println("**** SupervisorStrategy Override Successfully ****");
    return new OneForOneStrategy(5, Duration.create(1, TimeUnit.MINUTES),
            DeciderBuilder.match(ResumeException.class, e -> SupervisorStrategy.resume())
            .match(RestartException.class, e -> SupervisorStrategy.restart())
            .match(StopException.class, e -> SupervisorStrategy.stop())
            .match(EsclateException.class, e -> SupervisorStrategy.escalate())
            .matchAny(e -> SupervisorStrategy.escalate()).build());

}}

In the receive() method when I throw the EsclateException the logs continues and not terminate the actor. But when I replace the exception code with throw new Error(), the actors stop the work and terminate. As from output, it seems that, my SupervisorStrategynot registered and actors run on default SupervisorStrategy. How can I register my strategies?

Below is my calling code:

public class JavaActorTest {

public static ActorSystem system;

@BeforeClass
public static void start() {
    system = ActorSystem.create("ActorLifeCycleTest");
}

@AfterClass
public static void cleanup() {
    JavaTestKit.shutdownActorSystem(system);
    system = null;
}

@Test
public void testActorCreation(){
    TestActorRef<JavaActor> actorRef = TestActorRef.create(system, Props.create(JavaActor.class));
    actorRef.tell("Ping", ActorRef.noSender());
    assertThat(true, is(true));
}}

Solution

  • An actor is supervised by its parent not by itself, so the supervisorStrategy of its parent actor is what will be applied when an actor fails.

    In your sample you do not include a parent of your own so the user guardian actor supervision is applied.

    You can read more about supervision in the docs here: http://doc.akka.io/docs/akka/2.4/general/supervision.html#supervision