Singleton cluster: a) multiple roles with proxy b) preStart?

New to clustering and singleton looks sufficient for me. Two questions:
a) If I create a singleton(s) with two roles (“A” and “B”), but set the actorProxy to not use roles, does it pick up one or the other? What happens if the one that we are using is down (say “A”) but the other singleton is up (say “B”)?
b) When a singleton actor becomes “it”, is there a preStart() that can be called? I noticed ClusterListener in the generic Cluster framework. Is there a singleton specific way?

Thanks much

Proxy must gave exact same role.

PreStart would be in the singleton actor itself. The constructor of the actor.

Thanks @patriknw- the first part was not obvious from the configuration at https://doc.akka.io/docs/akka/current/typed/cluster-singleton.html:

akka.cluster.singleton-proxy {
  # The actor name of the singleton actor that is started by the ClusterSingletonManager
  singleton-name = ${akka.cluster.singleton.singleton-name}
  
  # The role of the cluster nodes where the singleton can be deployed. 
  # If the role is not specified then any node will do.
  role = ""
```.
It made it look like "If role is not specified (for singleton-proxy), then any node (regardless of its role) will do."

Thanks, that is confusing. I have improved in https://github.com/akka/akka/pull/29015

1 Like

@patriknw I tried to do something like:

 def apply(): Behavior[Command] = {
   logger.info("Activating Actor.")

And it gets printed on all the nodes even though queries from all nodes are correctly going to a single node. How do I know I am the chosen Actor for a singleton. Thanks

That apply is called when you initialize the ClusterSingleton. That isn’t a running actor yet. If you use Behaviors.setup and pu the log inside there you will only see it on the active node.

Thanks @patriknw. That mostly works except during bootstrap sometimes I see two nodes print that message (with the latest node being the “it” node). Can a singleton node move as the cluster evolves and gets more nodes? I am not using a lease because it is not absolutely necessary that only a single node be there. I start a rather expensive daemon on the active node and so want to start it when I get picked and shut it down when I am not longer “it”. I thought about checking who the picked node is but couldn’t figure out how for Singleton clusters. Thanks again

That should never happen, so it is either that you have ended up with more than one cluster some how (for example a “split brain”, read more here) or a bug in the Akka Cluster Singleton (unlikely).

Thanks I suspected as such. In my case, split brain is not a problem per se. But I’m not clear on what happens when the singleton clusters merge. I am not using auto downing. Do we now have two singletons that are active (which new members picking up the correct singleton Actor?

On a related node, how do you do something like
Cluster(system).state for a singleton cluster? I cannot subscribe/see any cluster state for singleton cluster.

Split brain will be a problem if you are using singletons for anything requiring consistency as having two or more clusters means there are one instance of the singleton in each cluster, each thinking it is the only instance.

The Cluster Singleton is not a part of the cluster state. It is built on top of the cluster infrastructure in Akka, so therefore there is no information about it in the cluster state.

There isn’t really any public API to the Cluster Singleton other than defining it with what behavior/props should be used and the proxy to interact with it.

See docs and samples here, in case you missed it: https://doc.akka.io/docs/akka/current/typed/cluster-singleton.html

Have been using those pages for guidance. E.g., the example talks about

val singletonManager = ClusterSingleton(system)

When discussing lease, it talks about

Cluster(system).selfAddress.hostPort

So, if I do Cluster(system) after I do ClusterSingleton(system), am I creating a new “Cluster” or accessing the underlying Cluster to the ClusterSingleton? The example seems simple but it discusses downing and I cannot do it unless I access the underlying Cluster and I am not on how to access that. Thanks again for all your help

Both Cluster and ClusterSingleton are extensions, a way to bind something to the lifecycle of a system, so every time you call Cluster(system) or ClusterSingleton(system) you get the instance for that system back.

For singleton that is mostly a way for the API to get access to the system (it also has a small cache to make sure that if you call init with the same SingletonActor several times in the same system, it only sets it up once and that you get the same proxy back each time.

Just accessing the Cluster extension does not form a cluster, I strongly recommend that you read up on forming a cluster and what that means: https://doc.akka.io/docs/akka/current/typed/cluster.html