Spectre.Operation.Control (Spectre v0.3.0)

Copy Markdown View Source

Portable control plane for pause, update, resume and terminal stop.

Summary

Functions

Increments the fencing generation, invalidating attempts fenced on the previous value.

Returns true when a command id is pending, last applied, or in history — the idempotency check behind {:duplicate, control} replies.

Records a command as finished, clearing the pending slot.

Creates the control plane for one loop, starting in :active state.

Commits a control command as the single pending command.

Returns true when the control plane has reached its terminal state.

Forces the control plane terminal, rejecting any still-pending command.

Validates the whole control plane: scalar fields, embedded commands, history identity and state/pending consistency.

Types

t()

@type t() :: %Spectre.Operation.Control{
  desired_state: :active | :paused | :terminal,
  generation: non_neg_integer(),
  history: [Spectre.Operation.Control.Command.t()],
  last_command: Spectre.Operation.Control.Command.t() | nil,
  loop_id: String.t(),
  pause_mode: :safe | :immediate,
  pending: Spectre.Operation.Control.Command.t() | nil,
  state: :active | :pause_requested | :paused | :stopping | :terminal,
  updated_at: non_neg_integer() | nil
}

Functions

bump_generation(control)

@spec bump_generation(t()) :: t()

Increments the fencing generation, invalidating attempts fenced on the previous value.

command_seen?(control, id)

@spec command_seen?(t(), String.t()) :: boolean()

Returns true when a command id is pending, last applied, or in history — the idempotency check behind {:duplicate, control} replies.

finish(control, command)

@spec finish(t(), Spectre.Operation.Control.Command.t()) :: t()

Records a command as finished, clearing the pending slot.

The finished command becomes last_command and the head of the bounded history; the control state follows the command's desired_state.

new(loop_id)

@spec new(String.t()) :: t()

Creates the control plane for one loop, starting in :active state.

request(control, command)

@spec request(t(), Spectre.Operation.Control.Command.t()) ::
  {:ok, t()} | {:duplicate, t()} | {:error, term()}

Commits a control command as the single pending command.

Replays of an already seen command id return {:duplicate, control}; a terminal control plane, a target mismatch or an already pending command return {:error, reason}. Pause-like commands move the state to :pause_requested.

terminal?(control)

@spec terminal?(t()) :: boolean()

Returns true when the control plane has reached its terminal state.

terminalize(control, reason \\ :loop_terminal)

@spec terminalize(t(), term()) :: t()

Forces the control plane terminal, rejecting any still-pending command.

A loop can reach a terminal outcome while a safe pause or update command is still pending; the command can no longer be applied, so it is finished as rejected before the terminal state is committed.

validate(control)

@spec validate(t()) :: :ok | {:error, term()}

Validates the whole control plane: scalar fields, embedded commands, history identity and state/pending consistency.

Returns :ok or {:error, reason} naming the first violated invariant.