Ankusa.Instance (ankusa v0.7.0)

Copy Markdown View Source

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.Registry forgets every name an instance process registered. Ankusa.Instance.RegistryWatch notices 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

child_spec(init_arg)

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.

start_link(config)

@spec start_link(Ankusa.Config.t() | atom()) :: Supervisor.on_start()

store?(config)

@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.