Behaviour for the external oracle used by Crown to determine leadership.
The oracle is the authority that grants and renews the crown. Implementations back this with an external service (database lease, Redis lock, etc.) so that leadership is enforced even across netsplits.
Callbacks
init/1- called once at startup with the oracle options.claim/1- attempt to claim the crown. Returns{true, refresh_delay, state}on success,{false, state}otherwise.refresh_delayis a millisecond duration or:infinity.refresh/1- renew an already-held crown. Same return shape asclaim/1.abdicate/1- optional. Called when the crown holder shuts down cleanly, allowing the oracle to release the claim early.handle_info/2- optional. Called when Crown receives an unexpected message, forwarding it to the oracle. Useful whenmonitor_leader: falseand the oracle needs to react to external signals (e.g. a webhook) to trigger a claim attempt. Returns the same shape asclaim/1andrefresh/1.
Summary
Callbacks
Release the crown on clean shutdown. Optional.
Attempt to claim the crown.
Handle an unexpected message forwarded by Crown. Optional.
Initialize the oracle with the given options.
Refresh an already-held crown.
Callbacks
@callback abdicate(state :: term()) :: :ok
Release the crown on clean shutdown. Optional.
@callback claim(state :: term()) :: {true, refresh_delay :: non_neg_integer() | :infinity, new_state :: term()} | {false, new_state :: term()}
Attempt to claim the crown.
@callback handle_info(msg :: term(), state :: term()) :: {true, refresh_delay :: non_neg_integer() | :infinity, new_state :: term()} | {false, new_state :: term()}
Handle an unexpected message forwarded by Crown. Optional.
Initialize the oracle with the given options.
When the options are a keyword list, Crown automatically injects a :crown_name
key (via Keyword.put_new/3) containing the Crown instance name atom. Oracles
can use this for namespacing (e.g. as a lock name).
@callback refresh(state :: term()) :: {true, refresh_delay :: non_neg_integer() | :infinity, new_state :: term()} | {false, new_state :: term()}
Refresh an already-held crown.