Handling errors with a cluster singleton


#1

Inside the akka-samples-cluster-java a cluster singleton one actor is instantiated with

    ActorSystem system = ActorSystem.create("ClusterSystem", config);

      ClusterSingletonManagerSettings settings = ClusterSingletonManagerSettings.create(system)
          .withRole("compute");
      system.actorOf(ClusterSingletonManager.props(
          Props.create(StatsService.class), PoisonPill.getInstance(), settings),
          "statsService");

From what I’ve read in the docs the “StatsService” actor will be a child of the User Guardian Actor.

Let’s say that in StatsService when it gets a message an IOException is thrown.

 public Receive createReceive() {
	... business logic
        ... somehow IOException is thrown (for example a file is read)
}

In this scenario, I’d like to shut down the entire cluster singleton when an IOException is thrown during processing.

In the fault tolerance docs I see the definition of a supervisor strategy

private static SupervisorStrategy strategy =
  new OneForOneStrategy(10, Duration.create(1, TimeUnit.MINUTES),
      DeciderBuilder
          .match(ArithmeticException.class, e -> SupervisorStrategy.resume())
          .match(NullPointerException.class, e -> SupervisorStrategy.restart())
          .match(IllegalArgumentException.class, e -> SupervisorStrategy.stop())
          .matchAny(o -> SupervisorStrategy.escalate())
          .build());

@Override
public SupervisorStrategy supervisorStrategy() {
  return strategy;
}

I’m a little confused on how in a cluster singleton how the supervisor strategy comes into play.

  1. If using the supervisor strategy, does that mean the parent actor should be a supervisor which spawn children?

  2. From reading this
    https://stackoverflow.com/questions/36701898/how-to-supervise-cluster-singleton-in-akka

Is the only way to supervise a cluster singleton to pass it in as a parameter when creating the cluster singleton?

class SupervisorActor(childProps: Props, override val supervisorStrategy) extends Actor {

  val child = context.actorOf(childProps, "supervised-child")

  def receive: Receive = {
    case msg => child forward msg
  }
}

context.actorOf(ClusterSingletonManager.props(
        singletonProps = Props(classOf[SupervisorActor], p, supervisorStrategy),
        terminationMessage = PoisonPill,
        settings = ClusterSingletonManagerSettings(context.system)),
        name = name)

Thank you in advance!


(Patrik Nordwall) #2
  1. Yes
  2. Yes

However it doesn’t make much sense to stop a cluster singleton instance since other nodes will not know and will continue to send to the expected singleton location resulting in deadLetters.