How to supervise cluster singleton in Akka?
Asked Answered
G

1

6

I'm trying to supervise an Akka Actor, more specifically a Cluster Singleton created using ClusterSingletonManager. I'm trying to achieve more control over exceptions, logs and Actor's life cycle.

Unfortunately, after implementing a solution, I made a Singleton Actor throw exceptions, but nothing was show in the logs, nor the Actor or Cluster was shutdown.

My implementation is as follows:

object SingletonSupervisor {
  case class CreateSingleton(p: Props, name: String)
}

class SingletonSupervisor extends Actor with ActorLogging {
  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 0, withinTimeRange = 1.minute) {
      case x: ActorInitializationException =>
        log.error(s"Actor=<${x.getActor}> trowed an exception=<${x.getCause}> with message=<${x.getMessage}>")
        Stop

      case x: ActorKilledException => Stop

      case x: DeathPactException => Stop

      case x: Exception =>
        log.error(s"Some actor threw an exception=<${x.getCause}> with message=<${x.getMessage}>, trace=<${x.getStackTrace}>")
        Escalate
    }

  def receive = {
    case CreateSingleton(p: Props, name: String) =>
      sender() ! context.actorOf(p)
      context.actorOf(ClusterSingletonManager.props(
        singletonProps = p,
        terminationMessage = PoisonPill,
        settings = ClusterSingletonManagerSettings(context.system)),
        name = name)
  }
}

So, is it even possible to supervisor a Cluster Singlegon? If possible, how should I attack this problem?

Glorygloryofthesnow answered 18/4, 2016 at 18:43 Comment(0)
E
6

One possible solution is creating supervisor actor that spawns given child with given supervisorStrategy and forwards messages to its child.

Here is supervisor actor:

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

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

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

and here is how you create supervised actor as cluster singleton

context.actorOf(ClusterSingletonManager.props(
        singletonProps = Props(classOf[SupervisorActor], p, supervisorStrategy),
        terminationMessage = PoisonPill,
        settings = ClusterSingletonManagerSettings(context.system)),
        name = name)
Ebberta answered 19/4, 2016 at 11:12 Comment(2)
Thank, I ended using this solution. But it still doesn't allow to completely supervise all actor tree.Glorygloryofthesnow
This answer is good enough that it's now in the Akka documentation: doc.akka.io/docs/akka/current/…Willawillabella

© 2022 - 2024 — McMap. All rights reserved.