portunus_supervisor behaviour (portunus v0.8.0)
View SourceA declarative, static supervisor. "Static" isn't an Erlang/OTP supervisor
type here: it means the child set is fixed, returned once by init/1,
unlike portunus_registry, whose children are added and removed at
runtime.
Only one of each child spec returned by init/1 can exist in the cluster at any
given time. The elected owner runs it under a local Erlang/OTP
supervisor, and portunus drives the cross-node leadership (ownership)
transfer.
It is a thin layer built on top of portunus_registry: start_link/3,4 reads
the desired children from init/1 once and registers each one, and returns
the underlying portunus_registry pid. The fixed child set fixes only what
runs, not where it runs, so which_children/1 reports what this node runs and
transfer/3 hands a child to a chosen node, the same deliberate rebalancing
that dynamic children get. Both take the returned handle, which is a
portunus_registry, so its other operations act on it too. The registry owns
the local supervisor, so the whole tree shares one lifetime and nothing is
leaked or orphaned. Children are namespaced by group (the
callback module by default, or #{group => G}), so several declarative
supervisors share one cluster without colliding. The callback mirrors
supervisor:
-callback init(Args :: term()) ->
{ok, {supervisor:sup_flags(),
[portunus_delayed_restart:child_spec_in()]}} |
ignore.Child specs are validated at registration: an invalid one aborts
start_link with {error, {invalid_child_spec, _}}.
Summary
Functions
Hand the child registered under Key to TargetNode, if this node currently
owns it. Delegates to portunus_registry:transfer/3; see there for the reply.
The children this node currently runs. Delegates to portunus_registry:which_children/1.
Callbacks
-callback init(term()) -> {ok, {supervisor:sup_flags(), [portunus_delayed_restart:child_spec_in()]}} | ignore.
Functions
-spec start_link(portunus:name(), module(), term()) -> {ok, pid()} | ignore | {error, term()}.
-spec start_link(portunus:name(), module(), term(), portunus_registry:registry_opts()) -> {ok, pid()} | ignore | {error, term()}.
-spec transfer(pid(), term(), node()) -> portunus:ok_or_error({no_contender, node()} | not_owner | no_quorum).
Hand the child registered under Key to TargetNode, if this node currently
owns it. Delegates to portunus_registry:transfer/3; see there for the reply.
-spec which_children(pid()) -> [{term(), pid() | restarting | undefined, worker | supervisor, [module()] | dynamic}].
The children this node currently runs. Delegates to portunus_registry:which_children/1.