Clarify supervision of singleton actors (#25681)
* Clarify supervision of singleton actors * Document supervision for typed singletons
This commit is contained in:
parent
bc7d77a801
commit
2045a0fbf7
4 changed files with 68 additions and 15 deletions
|
|
@ -4,16 +4,15 @@
|
|||
|
||||
package jdocs.akka.cluster.typed;
|
||||
|
||||
import akka.actor.typed.ActorRef;
|
||||
import akka.actor.typed.ActorSystem;
|
||||
import akka.actor.typed.Behavior;
|
||||
import akka.actor.typed.Props;
|
||||
import akka.actor.typed.*;
|
||||
import akka.actor.typed.javadsl.Behaviors;
|
||||
|
||||
//#import
|
||||
import akka.cluster.typed.ClusterSingleton;
|
||||
import akka.cluster.typed.ClusterSingletonSettings;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
//#import
|
||||
|
||||
public class SingletonCompileOnlyTest {
|
||||
|
|
@ -49,21 +48,41 @@ public class SingletonCompileOnlyTest {
|
|||
public static void example() {
|
||||
|
||||
ActorSystem system = ActorSystem.create(
|
||||
Behaviors.empty(), "SingletonExample"
|
||||
Behaviors.empty(), "SingletonExample"
|
||||
);
|
||||
|
||||
//#singleton
|
||||
ClusterSingleton singleton = ClusterSingleton.get(system);
|
||||
// Start if needed and provide a proxy to a named singleton
|
||||
ActorRef<CounterCommand> proxy = singleton.spawn(
|
||||
counter("TheCounter", 0),
|
||||
counter("TheCounter", 0),
|
||||
"GlobalCounter",
|
||||
Props.empty(),
|
||||
ClusterSingletonSettings.create(system),
|
||||
new GoodByeCounter()
|
||||
);
|
||||
|
||||
proxy.tell(new Increment());
|
||||
//#singleton
|
||||
|
||||
}
|
||||
|
||||
public static void backoff() {
|
||||
|
||||
ActorSystem system = ActorSystem.create(
|
||||
Behaviors.empty(), "SingletonExample"
|
||||
);
|
||||
|
||||
//#backoff
|
||||
ClusterSingleton singleton = ClusterSingleton.get(system);
|
||||
ActorRef<CounterCommand> proxy = singleton.spawn(
|
||||
Behaviors.supervise(counter("TheCounter", 0))
|
||||
.onFailure(SupervisorStrategy.restartWithBackoff(Duration.ofSeconds(1), Duration.ofSeconds(10), 0.2)),
|
||||
"GlobalCounter",
|
||||
Props.empty(),
|
||||
ClusterSingletonSettings.create(system),
|
||||
new GoodByeCounter()
|
||||
);
|
||||
|
||||
proxy.tell(new Increment());
|
||||
//#singleton
|
||||
//#backoff
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
package docs.akka.cluster.typed
|
||||
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.ActorSystem
|
||||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.Props
|
||||
import akka.actor.typed.{ ActorRef, ActorSystem, Behavior, Props, SupervisorStrategy }
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import scala.concurrent.duration._
|
||||
|
||||
object SingletonCompileOnlySpec {
|
||||
|
||||
|
|
@ -39,7 +37,8 @@ object SingletonCompileOnlySpec {
|
|||
val singletonManager = ClusterSingleton(system)
|
||||
// Start if needed and provide a proxy to a named singleton
|
||||
val proxy: ActorRef[CounterCommand] = singletonManager.spawn(
|
||||
behavior = counter("TheCounter", 0),
|
||||
behavior = Behaviors.supervise(counter("TheCounter", 0))
|
||||
.onFailure[Exception](SupervisorStrategy.restart),
|
||||
"GlobalCounter",
|
||||
Props.empty,
|
||||
ClusterSingletonSettings(system),
|
||||
|
|
@ -49,4 +48,14 @@ object SingletonCompileOnlySpec {
|
|||
proxy ! Increment
|
||||
//#singleton
|
||||
|
||||
//#backoff
|
||||
val proxyBackOff: ActorRef[CounterCommand] = singletonManager.spawn(
|
||||
behavior = Behaviors.supervise(counter("TheCounter", 0))
|
||||
.onFailure[Exception](SupervisorStrategy.restartWithBackoff(1.second, 10.seconds, 0.2)),
|
||||
"GlobalCounter",
|
||||
Props.empty,
|
||||
ClusterSingletonSettings(system),
|
||||
terminationMessage = GoodByeCounter
|
||||
)
|
||||
//#backoff
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,15 @@ with different settings if needed.
|
|||
|
||||
## 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))
|
||||
There are two actors that could potentially be supervised. For the `consumer` singleton created above these would be:
|
||||
|
||||
* Cluster singleton manager e.g. `/user/consumer` which runs on every node in the cluster
|
||||
* The user actor e.g. `/user/consumer/singleton` which the manager starts on the oldest node
|
||||
|
||||
The Cluster singleton manager actor should not have its supervision strategy changed as it should always be running.
|
||||
However it is sometimes useful to add supervision for the user actor.
|
||||
To accomplish this 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-docs/src/test/scala/docs/cluster/singleton/ClusterSingletonSupervision.scala) { #singleton-supervisor-actor }
|
||||
|
|
|
|||
|
|
@ -57,6 +57,23 @@ Scala
|
|||
Java
|
||||
: @@snip [SingletonCompileOnlyTest.java](/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/SingletonCompileOnlyTest.java) { #import #singleton }
|
||||
|
||||
## Supervision
|
||||
|
||||
The default @ref[supervision strategy](./fault-tolerance.md) when an exception is thrown is for an actor to be stopped.
|
||||
The above example overrides this to `restart` to ensure it is always running. Another option would be to restart with
|
||||
a backoff:
|
||||
|
||||
|
||||
Scala
|
||||
: @@snip [SingletonCompileOnlySpec.scala](/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/SingletonCompileOnlySpec.scala) { #backoff}
|
||||
|
||||
Java
|
||||
: @@snip [SingletonCompileOnlyTest.java](/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/SingletonCompileOnlyTest.java) { #backoff}
|
||||
|
||||
Be aware that this means there will be times when the singleton won't be running as restart is delayed.
|
||||
See @ref[Fault Tolerance](./fault-tolerance.md) for a full list of supervision options.
|
||||
|
||||
|
||||
## Accessing singleton of another data centre
|
||||
|
||||
TODO
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue