Creating a supervised global singleton genserver

We have a process that is registered using:

def start_link do
  case GenServer.start_link(__MODULE__, :ok, name: {:global, __MODULE__}) do
    {:ok, pid} -> "---- #{__MODULE__} worker started"
      {:ok, pid}
    {:error, {:already_started, pid}} -> "---- #{__MODULE__} worker already running"
      {:ok, pid}

Currently, if we kill the node running the singleton, the other node doesn’t seem to notice that the node is down, and the killed processes aren’t restarted.

E.g Supervisor.which_children on the remaining node returns the remote pid #PID<4554, 234, 0>, and :global.whereis_name returns :undefined

What we would like to see is that the supervisor restarts the process on the remaining node, but so far our attempts have been fruitless.

1 Like

This is a good example:


Thanks Dom! Singleton worked :slight_smile:

Another option, which I’ve seen in a codebase, is to lazily restart the GenServer when a client call notices that it’s down. This is instead of monitoring the process on every node and handling the :DOWN message as Singleton does.


## Client API
def foo(name \\ __MODULE__) do
  case GenServer.whereis({:global, name}) do
    nil ->
      # restart on an available node, e.g. via Supervisor.restart_child{:global, name}, :foo)
    pid ->, :foo)

## Server callbacks
def handle_call(:foo, _from, state) do
  # update state and reply