Supervises one instance of the framework from a %Ankusa.Config{}. Only the
children for configured roles boot, so the same code runs any role set. The
boundaries between components are durable state (this node's store), not
function calls. The store is node-local, so every role that reads or writes
hooks has to run on the node that holds it.
Failure domains
The tree is :rest_for_one, and what the instance does when a part of it
fails depends on which part:
- The core — the claim stores' breaker table
(
Ankusa.ClaimCheck.Stores), the store, the source store and the edge subtree (routes, queue writer, quarantine, rate limiter, batchers, ingress listener) — is what acks hooks. A crash there restarts whatever depends on it: the edge restarts with the store it writes to, and everything started after it restarts with the edge. A core that keeps crashing exhausts this supervisor's budget and the instance stops, for its parent to restart. - Every other domain — dispatch, archive/storage, store backup,
lifecycle events, metrics, and the admin, route-admin, claim-check and
metrics listeners — runs under
Ankusa.Instance.Isolated. It has its own restart budget, and when that is exhausted it is restarted later with backoff instead of taking the instance down. A broken sink, a port someone else took or a full object store stops that domain, not the edge acking hooks; the hooks wait in the store and are dispatched when the domain returns. - The registry — a restart of
Ankusa.Registryforgets every name an instance process registered.Ankusa.Instance.RegistryWatchnotices and stops the instance, so whatever supervises it starts it again, every process registered anew.
Stopping
A stop that should not reset a request in flight runs
Ankusa.Instance.Drain.run/1 first (both applications do, from prep_stop/1):
/ready flips to draining, the edge's ingress listener (the :ingress child
of the edge subtree) closes after the requests it is serving, and the
batchers empty. Then this tree stops in reverse start order: dispatch writes
its outcomes, the backup takes its final checkpoint, the store closes.
Summary
Functions
The child spec for the instance config describes. Building it stores the
config (Ankusa.put_config/1), so the parent's spec, its supervisor reports
and :sys.get_status/1 name only the instance, and every (re)start reads the
config back. Build it only for an instance you are about to start: it
replaces that name's stored config.
Whether this instance runs the node-local store (Ankusa.Store) and the audit
trail written into it (Ankusa.Audit): any of the :edge, :dispatch or
:storage roles, the admin API (every change it makes is audited), or a
source store that accepts writes.
Functions
The child spec for the instance config describes. Building it stores the
config (Ankusa.put_config/1), so the parent's spec, its supervisor reports
and :sys.get_status/1 name only the instance, and every (re)start reads the
config back. Build it only for an instance you are about to start: it
replaces that name's stored config.
@spec start_link(Ankusa.Config.t() | atom()) :: Supervisor.on_start()
@spec store?(Ankusa.Config.t()) :: boolean()
Whether this instance runs the node-local store (Ankusa.Store) and the audit
trail written into it (Ankusa.Audit): any of the :edge, :dispatch or
:storage roles, the admin API (every change it makes is audited), or a
source store that accepts writes.