Packages
dynamic_supervisor_proxy
0.1.71
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Starts a module-based dynamic supervisor process with a registered name. Will wait a bit if the supervisor name is still registered on restarts.
Current section
Files
Jump to
Current section
Files
lib/dynamic_supervisor/proxy/starter.ex
defmodule DynamicSupervisor.Proxy.Starter do
use PersistConfig
alias DynamicSupervisor.Proxy.Log
@supervisor_restart_backoff get_env(:supervisor_restart_backoff)
@timeout get_env(:timeout)
@times get_env(:times)
@doc """
Starts a module-based dynamic supervisor process with the given `module` and
`init_arg`. The `:name` option _must_ be specified in order to register a
supervisor name. Will wait a bit if the supervisor name is still registered
on restarts. See [Supervisor restart backoff](#{@supervisor_restart_backoff}).
"""
@spec start_link(module, term, GenServer.options()) :: Supervisor.on_start()
def start_link(module, init_arg, opts) do
case DynamicSupervisor.start_link(module, init_arg, opts) do
{:ok, pid} ->
{:ok, pid}
{:error, {:already_started, pid} = reason} ->
name = opts[:name]
still_registered = {name, @timeout, @times, reason, __ENV__}
:ok = Log.warning(:still_registered, still_registered)
:ok = wait(name, pid, @times)
DynamicSupervisor.start_link(module, init_arg, opts)
other ->
other
end
end
## Private functions
# On restarts, wait if `name` still registered...
@spec wait(GenServer.name(), pid, non_neg_integer) :: :ok
defp wait(_name, _pid, 0) do
:ok
end
defp wait(name, pid, times_left) do
Process.sleep(@timeout)
times_left = times_left - 1
case Process.whereis(name) do
nil ->
times = @times - times_left
now_unregistered = {name, pid, @timeout, times, __ENV__}
:ok = Log.notice(:now_unregistered, now_unregistered)
^pid ->
log(name, pid, times_left)
wait(name, pid, times_left)
end
end
@spec log(GenServer.name(), pid, non_neg_integer) :: :ok
defp log(name, pid, 0) do
remains_registered = {name, pid, @timeout, @times, __ENV__}
:ok = Log.error(:remains_registered, remains_registered)
end
defp log(name, pid, times_left) do
still_registered = {{name, pid}, @timeout, times_left, __ENV__}
:ok = Log.warning(:still_registered, still_registered)
end
end