I created a GenServer to keep track of the current index in case the client reconnects to the socket. I intend to only use one GenServer.
I can make the GenServer start automatically by adding it to the children list of supervisor but my GenServer state is depended on the result of a query so I cannot put it there.
children = [
# Start the Ecto repository
Senti.Repo,
...
{Senti.QuestionState, [%{}]}
]
I started the GenServer in my join callback. I’m aware that the start_link will always be called when there are new clients connected but I have no idea where should I put this one.
I have my code below to describe more about my issue.
Application.start_phase/3 seems to be a good fit. Add a DynamicSupervisor to the main supervision tree and make it start and supervise your GenServer in the start_phase.
I am not sure you need start_phase at all. You can query your repo in the init of your GenServer and that will be executed before the supervisor starts the next child.
So you can start your repo, start the GenServer that depends on your repo, and then start the rest of the app (web stack with channels).
I don’t know because I don’t know why you need a session genserver for each channel process.
But I guess it could be more direct to handle the :error in lookup/1 directly.
defmodule QuestionState do
def via(session_id) do
{:via, Registry, {MyRegistry, {:session, session_id}}}
end
def start_link(session_id) do
GenServer.start_link(__MODULE__, init_arg, name: via(session_id))
end
def start_supervised(session_id) do
SessionSupervisor.start(presentation_state, session_id)
end
def lookup(session_id) do
case start_supervised(session_id) do
{:ok, pid} -> {:ok, pid}
{:error, {:already_started, pid}} -> {:ok, pid}
end
end
end