I have an Elixir/Erlang process tree:
parent (Supervisor)
├── child1 (GenServer)
└── child2 (GenServer)
child1 (a DB client) has information that child2 needs to use. What's a good way to pass a reference from the Supervisor process to child2 so that child2 will always have a valid reference to child1? Do I just need to restructure my app so that child2 is supervised by child1?
The simplest way would probably be for child1
and child2
to be registered under local aliases. You can do that while starting your GenServer
by passing the name
option:
defmodule Child1 do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
end
In this case a process backed by the Child1
module will be registered locally under an alias Child1
. Then if you want to send it messages you can use that alias instead of a PID
.
defmodule Child1 do
# ...
def get_data do
GenServer.call(__MODULE__, :get_data)
end
def handle_call(:get_data, _from, state) do
{:reply, extract_data_from_state(state), state}
end
end
If you want a more complex solution where for example many different processes of the same type may be registered, take a look at the gproc library