Backplane.AgentRuntime.Store behaviour (backplane_agent_runtime v1.6.0)

Copy Markdown

Runtime storage contract for versioned run transitions.

A record is accepted only when its expected revision is the currently committed revision. A successful commit returns the next revision and outbox intents. Hosts must execute effects only after that acknowledgement.

Durable adapters also atomically fence an older executor before recovery. fence/6 compares both the committed revision and incarnation, advances both, and returns the fenced run. It must not dispatch or replay any effect.

Summary

Callbacks

acknowledge_commit(term, map, map)

@callback acknowledge_commit(term(), map(), map()) ::
  {:ok, %{revision: non_neg_integer()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

capabilities()

@callback capabilities() :: map()

fence(term, term, non_neg_integer, non_neg_integer, pos_integer)

(optional)
@callback fence(term(), term(), non_neg_integer(), non_neg_integer(), pos_integer()) ::
  {:ok, %{revision: non_neg_integer(), run: map()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

load(term, term, keyword)

@callback load(term(), term(), keyword()) ::
  {:ok, map()} | {:error, Backplane.AgentRuntime.Error.t()}

mode()

@callback mode() :: :ephemeral | :durable

new(non_neg_integer)

@callback new(non_neg_integer()) :: {:ok, term()}

store(term, map, map)

@callback store(term(), map(), map()) ::
  {:ok, %{revision: non_neg_integer(), outbox: list()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

Functions

acknowledge_commit(impl, context, stage, meta)

@spec acknowledge_commit(module(), term(), term(), map()) ::
  {:ok, %{revision: non_neg_integer(), outbox: list()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

fence(impl, context, run_id, expected_revision, current_incarnation, next_incarnation)

@spec fence(
  module(),
  term(),
  term(),
  non_neg_integer(),
  non_neg_integer(),
  pos_integer()
) ::
  {:ok, %{revision: pos_integer(), run: map()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

Atomically fences the committed incarnation of a durable run.

The adapter must compare expected_revision and current_incarnation in the same durable transaction that writes next_incarnation and the next revision. A stale executor therefore cannot regain ownership after restart.

stage(impl, context, record, meta)

@spec stage(module(), term(), map(), map()) ::
  {:ok, %{revision: non_neg_integer(), outbox: list(), stage: term()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

store(impl, context, record, meta)

@spec store(module(), term(), map(), map()) ::
  {:ok, %{revision: non_neg_integer(), outbox: list()}}
  | {:error, Backplane.AgentRuntime.Error.t()}

validate_capabilities(impl)

@spec validate_capabilities(module()) ::
  {:ok, map()} | {:error, Backplane.AgentRuntime.Error.t()}

validate_durable_capabilities(impl)

@spec validate_durable_capabilities(module()) ::
  {:ok, map()} | {:error, Backplane.AgentRuntime.Error.t()}

validate_mode(impl)

@spec validate_mode(module()) ::
  {:ok, atom()} | {:error, Backplane.AgentRuntime.Error.t()}