Preserving the state of cluster singleton

Is there a way to transfer the state from an old singleton instance to a new one when the oldest node in the cluster changes?

I don’t know how bad this solution is, but it works.

public void postStop() {
    ActorContext context = getContext();
    ActorSystem system = context.getSystem();
    Cluster cluster = Cluster.get(system);
    Member me = cluster.selfMember();, false)
            .filter(member -> !me.equals(member))
            .filter(member -> member.status().equals(MemberStatus.up()))
            .sorted((a, b) -> a.isOlderThan(b) ? -1 : 1)
            .map(address -> context.actorSelection(address + "/user/some-singleton-proxy"))
            .map(selection -> selection.resolveOne(Duration.ofMillis(150)))
            .ifPresent(cs -> cs.thenAccept(proxy -> {
                proxy.tell(new InitializeCommand(data), ActorRef.noSender());

A solution that tries to message the next node is tricky since it is going away but would have to stay alive with some form of redelivery to guarantee the state was successfully delivered. There are definitely scenarios where this may break - for example if the cluster is partitioned and the singleton half is downed or if the node has a hard crash.

I’d recommend that you instead look at either persisting the state with Akka Persistence or some other external storage to be able to load it when started or distributed data to make the state eventually available on any nodes the singleton may start on.

As an example both these strategies are used in the Cluster Sharding coordinator to share the set of running shards when the singleton moves around.

1 Like

Thanks for the answer. Yes, I know this is not a very reliable way and it is better to use other approaches. I am currently studying Akka modules, figuring out the limits of applicability of each of them, so the question is more theoretical.