Singleton - global, supervised singleton processes for Elixir

I created a tiny library which supervises “singleton” processes, using Erlang’s global module.

Processes which are started with Singleton.start_child/3 are guaranteed to run on one single node in your Elixir cluster. The nodes that don’t run the process, monitor it so that when it dies, it gets respawned, possibly on another node. This monitoring part is something that global doesn’t do for you.

It feels a bit “thin” for a hex package but I find it kind of useful (I’m using it as part of a bigger project, obviously). Anyway, check it out: GitHub - arjan/singleton: Global, supervised singleton processes for Elixir

11 Likes

Sounds useful, thanks. Might be something for a lighting talk? Judging by the amount of hex packages, perhaps even a Arjans toolbox-talk :wink:

2 Likes

Hi.
Thanks for putting the library together.

Before I found it, I’ve been trying to hack my own implementation and I ended up with a very similar code as yours.

However, both your code and mine suffers from an unexpected behavior.

When a 2nd node joins the cluster, I do see:

23:24:54.246 [info]  global: Name conflict terminating {:singleton, #PID<18487.303.0>}

But what is unexpected is that not only the singleton process is terminated, but the whole application on one of the nodes:

23:25:47.517 [info]  Application wpc5_singleton exited: killed

And one of the nodes basically is left in a state where my own application is not running, only the “libraries” continue running.

I’ve been struggling with the same issue in my own implementation.

I created a DynamicSupervisor for the singleton process, similarly to you and I was hoping that it will “shield” the main Application supervisor from crashing when the :global registry kills one of the singleton processes.

However, that doesn’t seem to be the case and the whole application dies regardless of multiple layers of supervisors :frowning:

Using Elixir version 1.12.3

1 Like