Convenience wrapper library around Erlang's global
module to ensure
a single instance of a process is kept running on a cluster of nodes.
The package can be installed as:
- Add
singleton
to your list of dependencies inmix.exs
:
def deps do
[{:singleton, "~> 1.0"}]
end
- Ensure
Singleton.Supervisor
is added to your application's supervision tree:
If your application includes a supervision tree in application.ex
, you can simply add Singleton.Supervisor
to the list of children.
children = [
# ...,
{Singleton.Supervisor, name: MyApp.Singleton}
]
supervisor = Supervisor.start_link(children, opts)
Use Singleton.start_child/4
to start a unique GenServer process.
Singleton.start_child(MyApp.Singleton, MyServer, [1], {:myserver, 1})
Execute this command on all nodes. The MyServer
GenServer is now
globally registered under the name {:global, {:myserver, 1}}
.
As soon as you connect nodes together, you'll see logger messages like:
04:56:29.003 [info] global: Name conflict terminating {MyServer, #PID<12501.68.0>}
When you now stop (or disconnect) the node on which the singleton process runs, you'll see it get started on one of the other nodes.
In case you run more than 3 singleton you'll need to increase the
max_restarts
of DynamicSupervisor
.
config :singleton,
dynamic_supervisor: [max_restarts: 100]
or add max_restarts
to your singleton supervisor spec:
{Singleton.Supervisor, name: MyApp.Singleton, max_restarts: 100}