diff --git a/akka-docs/src/main/paradox/cluster-singleton.md b/akka-docs/src/main/paradox/cluster-singleton.md index 3167feae03..7a33d53eda 100644 --- a/akka-docs/src/main/paradox/cluster-singleton.md +++ b/akka-docs/src/main/paradox/cluster-singleton.md @@ -156,4 +156,23 @@ or create it from another config section with the same layout as below. `Cluster a parameter to the `ClusterSingletonProxy.props` factory method, i.e. each singleton proxy can be configured with different settings if needed. -@@snip [reference.conf]($akka$/akka-cluster-tools/src/main/resources/reference.conf) { #singleton-proxy-config } \ No newline at end of file +@@snip [reference.conf]($akka$/akka-cluster-tools/src/main/resources/reference.conf) { #singleton-proxy-config } + +## Supervision + +Sometimes it is useful to add supervision for the Cluster Singleton itself. To accomplish this you need to add a parent supervisor actor which will be used to create the 'real' singleton instance. Below is an example implementation (credit to [this StackOverflow answer](https://stackoverflow.com/a/36716708/779513)) + +Scala +: @@snip [ClusterSingletonSupervision.scala]($akka$/akka-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala) { #singleton-supervisor-actor } + +Java +: @@snip [SupervisorActor.java]($akka$/akka-docs/src/test/java/jdocs/cluster/singleton/SupervisorActor.java) { #singleton-supervisor-actor } + +And used here + +Scala +: @@snip [ClusterSingletonSupervision.scala]($akka$/akka-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala) { #singleton-supervisor-actor-usage } + +Java +: @@snip [ClusterSingletonSupervision.java]($akka$/akka-docs/src/test/java/jdocs/cluster/singleton/ClusterSingletonSupervision.java) { #singleton-supervisor-actor-usage-imports } +@@snip [ClusterSingletonSupervision.java]($akka$/akka-docs/src/test/java/jdocs/cluster/singleton/ClusterSingletonSupervision.java) { #singleton-supervisor-actor-usage } diff --git a/akka-docs/src/test/java/jdocs/cluster/singleton/ClusterSingletonSupervision.java b/akka-docs/src/test/java/jdocs/cluster/singleton/ClusterSingletonSupervision.java new file mode 100644 index 0000000000..8f4ded237a --- /dev/null +++ b/akka-docs/src/test/java/jdocs/cluster/singleton/ClusterSingletonSupervision.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015-2018 Lightbend Inc. + */ + +package jdocs.cluster.singleton; + +import akka.actor.AbstractActor; +import akka.actor.ActorRef; +import akka.actor.Props; +import akka.actor.SupervisorStrategy; + +//#singleton-supervisor-actor-usage-imports +import akka.actor.PoisonPill; +import akka.actor.Props; +import akka.cluster.singleton.ClusterSingletonManager; +import akka.cluster.singleton.ClusterSingletonManagerSettings; +//#singleton-supervisor-actor-usage-imports + +abstract class ClusterSingletonSupervision extends AbstractActor { + + public ActorRef createSingleton(String name, Props props, SupervisorStrategy supervisorStrategy) { + //#singleton-supervisor-actor-usage + return getContext().system().actorOf( + ClusterSingletonManager.props( + Props.create(SupervisorActor.class, () -> new SupervisorActor(props, supervisorStrategy)), + PoisonPill.getInstance(), + ClusterSingletonManagerSettings.create(getContext().system())), + name = name); + //#singleton-supervisor-actor-usage + } +} \ No newline at end of file diff --git a/akka-docs/src/test/java/jdocs/cluster/singleton/SupervisorActor.java b/akka-docs/src/test/java/jdocs/cluster/singleton/SupervisorActor.java new file mode 100644 index 0000000000..25aea0d8fd --- /dev/null +++ b/akka-docs/src/test/java/jdocs/cluster/singleton/SupervisorActor.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2015-2018 Lightbend Inc. + */ + +package jdocs.cluster.singleton; + +//#singleton-supervisor-actor +import akka.actor.AbstractActor; +import akka.actor.AbstractActor.Receive; +import akka.actor.ActorRef; +import akka.actor.Props; +import akka.actor.SupervisorStrategy; + +public class SupervisorActor extends AbstractActor { + final Props childProps; + final SupervisorStrategy supervisorStrategy; + final ActorRef child; + SupervisorActor(Props childProps, SupervisorStrategy supervisorStrategy) { + this.childProps = childProps; + this.supervisorStrategy = supervisorStrategy; + this.child = getContext().actorOf(childProps, "supervised-child"); + } + + @Override + public SupervisorStrategy supervisorStrategy() { + return supervisorStrategy; + } + + @Override + public Receive createReceive() { + return receiveBuilder() + .matchAny(msg -> child.forward(msg, getContext())) + .build(); + } +} +//#singleton-supervisor-actor \ No newline at end of file diff --git a/akka-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala b/akka-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala new file mode 100644 index 0000000000..27afa66788 --- /dev/null +++ b/akka-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 Lightbend Inc. + */ + +package docs.cluster.singleton + +//#singleton-supervisor-actor +import akka.actor.{ Actor, Props, SupervisorStrategy } +class SupervisorActor(childProps: Props, override val supervisorStrategy: SupervisorStrategy) extends Actor { + val child = context.actorOf(childProps, "supervised-child") + + def receive = { + case msg ⇒ child forward msg + } +} +//#singleton-supervisor-actor + +import akka.actor.Actor +abstract class ClusterSingletonSupervision extends Actor { + import akka.actor.{ ActorRef, Props, SupervisorStrategy } + def createSingleton(name: String, props: Props, supervisorStrategy: SupervisorStrategy): ActorRef = { + //#singleton-supervisor-actor-usage + import akka.actor.{ PoisonPill, Props } + import akka.cluster.singleton.{ ClusterSingletonManager, ClusterSingletonManagerSettings } + context.system.actorOf( + ClusterSingletonManager.props( + singletonProps = Props(classOf[SupervisorActor], props, supervisorStrategy), + terminationMessage = PoisonPill, + settings = ClusterSingletonManagerSettings(context.system)), + name = name) + //#singleton-supervisor-actor-usage + } +}