TL;DR By only given the pid for a supervisor and the client side(the APIs) of a child GenServer(The only parameter for those APIs are the pid of the child GenServer for sure, if still unclear, see the example below for Storage.get/1
). Without naming the child process, running Supervisor.which_children/1
or switching to DynamicSupervisor + Supervisor.start_child/2
. How do I get the pid of the child process programmatically upon calling Supervisor.start_link/1
? How can I communicate with the child process?
I have a question regarding how to access the child pid given the supervisor. For example, I have a GenServer which is just in charge of storing a value and a Supervisor which supervises the GenServer, which looks like
Summary
`
defmodule Storage do
use GenServer
def start_link(init_value) do
GenServer.start_link(Storage, init_value, [])
end
def get(pid) do
GenServer.call(pid, :get)
end
def init(init_value) do
{:ok, init_value}
end
def handle_call(:get, _from, state) do
{:reply, state, state}
end
end
defmodule Storage.Supervisor do
use Supervisor
def start_link(_) do
Supervisor.start_link(MODULE, :ok)
end
def init(:ok) do
children = [
{Storage, 1}
]
Supervisor.init(children, [strategy: :one_for_one])
end
end
`
The problem is that, I can use Storage.Supervisor.start_link/1
to start the Supervisor but it’s returning {ok, <supervisor pid>}
and I can’t send the child process any message with that pid. So far I’ve explored the following options:
- use
name
option inGenServer.init
. However, that doesn’t work in my scenario when I want to spawn multiple Supervisors. - use
Supervisor.which_children/1
. I think this might work but where should I call it? I just get a feeling that using it might not be the best practice. - Switch to DynamicSupervisor and use
Supervisor.start_child/2
. However, I think since it’s a one for one supervisor. Do I really need to make it that complex by introducing things that I don’t really need?
So I’m wondering if there’s a way for Supervisor.init/1
to report back the child pids that it started? Or in that case, it’s impossible that I’ll either need to look it up by Supervisor.which_children/1
or using Supervisor.start_child/2
? Any help is appreciated. Thanks!