defmodule DynamicSupervisor.Proxy do use PersistConfig @supervisor_restart_backoff get_env(:supervisor_restart_backoff) @moduledoc """ Starts a module-based dynamic supervisor process with a registered name. Will wait a bit if the supervisor name is still registered on restarts. See [Supervisor restart backoff](#{@supervisor_restart_backoff}). """ @doc """ Uses `DynamicSupervisor`. Also either aliases `DynamicSupervisor.Proxy` (this module) and requires the alias or imports `DynamicSupervisor.Proxy`. Finally, it will inject the default implementation of the `c:DynamicSupervisor.init/1` callback. ## Examples use DynamicSupervisor.Proxy, alias: Proxy use DynamicSupervisor.Proxy """ defmacro __using__(options) do alias = options[:alias] if alias do quote do use DynamicSupervisor alias unquote(__MODULE__), as: unquote(alias) require unquote(alias) @impl DynamicSupervisor @spec init(term) :: {:ok, DynamicSupervisor.sup_flags()} | :ignore def init(_arg), do: DynamicSupervisor.init(strategy: :one_for_one) defoverridable init: 1 end else quote do use DynamicSupervisor import unquote(__MODULE__) @impl DynamicSupervisor @spec init(term) :: {:ok, DynamicSupervisor.sup_flags()} | :ignore def init(_arg), do: DynamicSupervisor.init(strategy: :one_for_one) defoverridable init: 1 end end end @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}). To start the supervisor, the `c:DynamicSupervisor.init/1` callback will be invoked in the given `module`, with `init_arg` as its argument. The `c:DynamicSupervisor.init/1` callback must return a supervisor specification which can be created with the help of the `DynamicSupervisor.init/1` function. ## Examples iex> defmodule DynSupOne do iex> use DynamicSupervisor.Proxy iex> iex> def start_link(:ok), do: start_link(DynSupOne, name: DynSupOne) iex> end iex> iex> children = [{DynSupOne, :ok}] iex> options = [name: Sup, strategy: :one_for_one] iex> {:ok, _pid} = Supervisor.start_link(children, options) iex> iex> %{active: 1, supervisors: 1} = Supervisor.count_children(Sup) iex> [{name, pid, :supervisor, [name]}] = Supervisor.which_children(Sup) iex> iex> name == DynSupOne and pid == Process.whereis(DynSupOne) true iex> defmodule DynSupTwo do iex> use DynamicSupervisor.Proxy iex> iex> def start_link(_), do: start_link(DynSupTwo, ??, name: DynSupTwo) iex> end iex> iex> defmodule DynSupThree do iex> use DynamicSupervisor.Proxy, alias: Proxy iex> iex> def start_link(OK) do iex> Proxy.start_link(__MODULE__, name: :three) iex> end iex> end iex> iex> children = [DynSupTwo, {DynSupThree, OK}] iex> options = [name: Sup, strategy: :one_for_one] iex> {:ok, _pid} = Supervisor.start_link(children, options) iex> iex> %{active: 2, supervisors: 2} = Supervisor.count_children(Sup) iex> children = Supervisor.which_children(Sup) iex> pid_two = Process.whereis(DynSupTwo) iex> pid_three = Process.whereis(:three) iex> iex> {DynSupTwo, pid_two, :supervisor, [DynSupTwo]} in children and ...> {DynSupThree, pid_three, :supervisor, [DynSupThree]} in children true """ defmacro start_link(module, init_arg \\ nil, opts) do quote bind_quoted: [mod: module, arg: init_arg, opts: opts] do DynamicSupervisor.Proxy.Starter.start_link(mod, arg, opts) end end end