NoNoncense.MachineId.LeaseManager (NoNoncense v2.0.0)

Copy Markdown View Source

Acquires and renews a machine ID lease through a pluggable NoNoncense.MachineId.Strategy, directly managing the configured NoNoncense factories.

Initial acquisition blocks startup. Once leased, the manager renews before the earlier of the configured renewal interval and the strategy-provided TTL. A confirmed loss or local expiry disables every configured factory, invokes :on_lease_lost with a reason, and schedules reacquisition. A successful reacquisition reinitializes the factories with the new machine ID.

An ambiguous renewal failure is retried while the known-valid window remains open. On graceful shutdown, the manager makes a best-effort call to the strategy's release/2 callback when it still holds a lease.

Options

  • :name - registered name (default NoNoncense.MachineId.LeaseManager)
  • :strategy (required) - a module implementing the NoNoncense.MachineId.Strategy behaviour
  • :strategy_opts - passed as-is to the strategy's callbacks (default [])
  • :lease_duration - the duration, in ms, to request from the strategy on every acquire/renew call (the strategy may grant a different actual duration; default 8 hours)
  • :renew_interval - how often to renew, in ms; should be comfortably shorter than the lease's actual TTL to allow for retries (default 30 minutes)
  • :acquire_timeout - max total time, in ms, to keep retrying acquisition at boot before giving up and failing start_link/1 (default 60_000; pass :infinity to retry forever)
  • :on_lease_lost - called with the reason for the lease loss. Can be used to halt the entire node, for example. Note that on lease loss, all NoNoncense factories are always disabled to preserve uniqueness guarantees.

Lease duration and renew interval

The defaults leave a wide recovery window for a temporary connection loss to your coordinator (e.g. your database), while still renewing well ahead of the lease's expiration. If you override these, keep that balance intact - most practical uses of nonce generation, such as ID generation, will grind to a halt if generation stops, so favor conservative, generous durations over aggressive, short ones. Machine IDs are meant to stay static for the lifetime of the node, so there's little to be gained from renewing more aggressively.

Summary

Functions

Returns a specification to start this module under a supervisor.

Signal to the lease manager that the lease was lost because of some external reason

Returns the currently leased machine ID.

Starts the lease manager, blocking until the initial lease is acquired (or :acquire_timeout elapses, in which case start_link/1 fails).

Types

opt()

@type opt() ::
  {:name, GenServer.name()}
  | {:strategy, module()}
  | {:strategy_opts, keyword()}
  | {:lease_duration, pos_integer()}
  | {:renew_interval, pos_integer()}
  | {:acquire_timeout, pos_integer() | :infinity}
  | {:on_lease_lost, (term() -> any())}
  | {:instances, [NoNoncense.init_opt()]}
  | {:lease_cache, GenServer.name()}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

lease_lost(name \\ __MODULE__, reason \\ :external)

@spec lease_lost(GenServer.name(), atom()) :: :ok

Signal to the lease manager that the lease was lost because of some external reason

machine_id(name \\ __MODULE__)

@spec machine_id(GenServer.name()) :: non_neg_integer()

Returns the currently leased machine ID.

start_link(opts)

@spec start_link([opt()]) :: GenServer.on_start()

Starts the lease manager, blocking until the initial lease is acquired (or :acquire_timeout elapses, in which case start_link/1 fails).

Options

  • :name - registered name (default NoNoncense.MachineId.LeaseManager)
  • :strategy (required) - a module implementing the NoNoncense.MachineId.Strategy behaviour
  • :strategy_opts - passed as-is to the strategy's callbacks (default [])
  • :lease_duration - the duration, in ms, to request from the strategy on every acquire/renew call (the strategy may grant a different actual duration; default 8 hours)
  • :renew_interval - how often to renew, in ms; should be comfortably shorter than the lease's actual TTL to allow for retries (default 30 minutes)
  • :acquire_timeout - max total time, in ms, to keep retrying acquisition at boot before giving up and failing start_link/1 (default 60_000; pass :infinity to retry forever)
  • :on_lease_lost - called with the reason for the lease loss. Can be used to halt the entire node, for example. Note that on lease loss, all NoNoncense factories are always disabled to preserve uniqueness guarantees.

Lease duration and renew interval

The defaults leave a wide recovery window for a temporary connection loss to your coordinator (e.g. your database), while still renewing well ahead of the lease's expiration. If you override these, keep that balance intact - most practical uses of nonce generation, such as ID generation, will grind to a halt if generation stops, so favor conservative, generous durations over aggressive, short ones. Machine IDs are meant to stay static for the lifetime of the node, so there's little to be gained from renewing more aggressively.