Cluster Singleton
For some use cases it is convenient and sometimes also mandatory to ensure that you have exactly one actor of a certain type running somewhere in the cluster.
Some examples:
- single point of responsibility for certain cluster-wide consistent decisions, or coordination of actions across the cluster system
- single entry point to an external system
- single master, many workers
- centralized naming service, or routing logic
Using a singleton should not be the first design choice. It has several drawbacks, such as single-point of bottleneck. Single-point of failure is also a relevant concern, but for some cases this feature takes care of that by making sure that another singleton instance will eventually be started.
This module is currently marked as may change in the sense of being the subject of active research. This means that API or semantics can change without warning or deprecation period and it is not recommended to use this module in production just yet—you have been warned.
Dependency
To use Akka Cluster Singleton Typed, add the module to your project:
- sbt
libraryDependencies += "com.typesafe.akka" %% "akka-cluster-typed" % "2.5.11"
- Maven
<dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-cluster-typed_2.12</artifactId> <version>2.5.11</version> </dependency>
- Gradle
dependencies { compile group: 'com.typesafe.akka', name: 'akka-cluster-typed_2.12', version: '2.5.11' }
Example
Any Behavior
can be run as a singleton. E.g. a basic counter:
- Scala
-
import akka.cluster.sharding.typed.ClusterShardingSettings import akka.cluster.sharding.typed.ShardingEnvelope import akka.cluster.sharding.typed.scaladsl.ClusterSharding import akka.cluster.sharding.typed.scaladsl.EntityTypeKey import akka.cluster.sharding.typed.scaladsl.EntityRef val sharding = ClusterSharding(system)
- Java
-
ClusterSharding sharding = ClusterSharding.get(system);
Then on every node in the cluster, or every node with a given role, use the ClusterSingleton
extension to spawn the singleton. Only a single instance will run in the cluster:
- Scala
-
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), "GlobalCounter", Props.empty, ClusterSingletonSettings(system), terminationMessage = GoodByeCounter ) proxy ! Increment
- Java
-
ClusterSingleton singleton = ClusterSingleton.get(system); // Start if needed and provide a proxy to a named singleton ActorRef<CounterCommand> proxy = singleton.spawn( counter("TheCounter", 0), "GlobalCounter", Props.empty(), ClusterSingletonSettings.create(system), new GoodByeCounter() ); proxy.tell(new Increment());