A simple process name registry using :pg
:
- Depends on the built-in Erlang's
:pg
app - Can be used with
:via
tuples for namingGenServers
,Agents
, etc. - Accepts any valid erlang term as process names.
- Supports several processses with the same name as long as they are not in the same node. Always picks the node closest to the process that called the function.
Let's say we define the following Agent
for keeping a counter:
defmodule Counter do
use Agent
def start_link(options \\ []) do
Agent.start_link(fn -> 0 end, options)
end
def increment(counter) do
Agent.get_and_update(counter, &{&1, &1 + 1})
end
end
We can now start it using ExReg
as name registry:
iex(1)> name = {:via, ExReg, {"metric", :my_counter}}
iex(2)> Counter.start_link(name: name)
{:ok, #PID<0.42.0>}
iex(3)> Counter.increment(name)
1
iex(4)> Counter.increment(name)
2
In a distributed environment, there are several things to notice:
-
ExReg
allows several processes to share the same name as long as they are not in the same Erlang node. -
When starting processes a process locally or sending messages exclusively to a local process:
- The name should match the type
{:local, term()}
e.g:Counter.start_link({:via, ExReg, {:local, {"metric", :my_counter}}})
- The function
ExReg.local({"metric", :my_counter})
can also be used to generate the local via tuple.
- The name should match the type
-
When sending messages to a named process, no matter its location:
- The name should be the term itself or
{:global, term()}
e.g:Counter.increment({:via, ExReg, {"metric", :my_counter}})
- The function
ExReg.global({"metric", :my_counter})
can also be used to generate the global via tuple.
- The name should be the term itself or
Add ExReg
to your list of dependencies in mix.exs
:
def deps do
[{:exreg, "~> 1.0"}]
end
Requires OTP 24 or more.
Alexander de Sousa
ExReg
is released under the MIT License. See the LICENSE file for further
details.