You should use :global module to find processes registered with :global. Process.whereis is for processes registered with Process.register.
case :global.whereis_name(user_id) do
:undefined ->
# You should probably check here for a race condition
Agent.start_link(fn -> %{} end, [name: {:global, user_id}])
pid when is_pid(pid) -> {:ok, pid}
_ -> {:error, :something_went_wrong}
end
As was already pointed out, the BEAM won’t let you start a second process with the same name. Since in your code you’re not handling the return:
you could just have Agent.start_link(fn -> %{} end, [name: {:global, user_id}]) and get the same result. Assuming that’s just example code and you do care about the response, you can do something like:
def ensure_agent(user_id) do
case Agent.start_link(fn -> %{} end, [name: {:global, user_id}]) do
{:ok, pid} -> {:ok, pid}
{:error, {:already_started, pid}} -> {:ok, pid}
response -> response
end
end
Your code can then call ensure_agent/1and will know that if {:ok, pid} is returned an agent is ready.