Docket (docket v0.1.0-dev)

Copy Markdown View Source

Public entry point for durable graph operations.

A runtime instance is one Docket.Runtime.Supervisor tree, identified by the name it was started under. Hosts usually define one with use Docket:

defmodule MyApp.Docket do
  use Docket,
    repo: MyApp.Repo,
    backend: Docket.Postgres
end

# in the application supervision tree
children = [MyApp.Docket]

Hosts save graph versions explicitly and use start_run, storage-backed reads, named signals, and await_run. Options given to the instance at startup own backend and execution policy. Per-call options carry only operation data and cannot replace instance configuration. Public durable calls resolve only :tenantless or an explicit {:tenant, id}; :system is reserved for internal dispatch/recovery.

For processless in-test execution of the same loop, use Docket.Test.

Delivery boundary

A durable backend commits each accepted run transition and its retained events atomically under the current claim and checkpoint fences. Node attempts are replayable and may execute more than once even though only one transition can commit. External effects require a cooperating idempotency scheme when duplicates are unacceptable. Checkpoint observers, notifications, and telemetry are best effort rather than durable delivery mechanisms.

Summary

Functions

Defines a host runtime module wrapping a named runtime instance

Polls durable operational state until waiting, terminal, poisoned, or timeout.

Cancels a durable active run and confirms the committed terminal state.

Child spec integration point: {Docket, name: MyRuntime, backend: ...} starts a Docket.Runtime.Supervisor tree.

Synchronously claims and drains due durable runs in a backend testing mode.

Fetches the persisted max-active-run default for a configured runtime.

Reads one retained durable event by its positive sequence number.

Reads the exact effective graph selected by a Docket.GraphRef.

Reads the latest retained durable event for a run.

Reads the reference for the newest distinct version of a graph ID.

Fetches the newest run summary matching the supplied tenant scope and optional graph/status filters.

Reads the last committed durable Docket.Run.

Inspects one owner scope's effective cap and aggregate admission state.

Reads a durable run plus token-free operational state.

Reads a page of retained durable events for a run.

Lists one graph ID's saved versions newest first under the resolved tenant.

Lists durable runs visible to the resolved tenant scope.

Initializes or updates the persisted max-active-run default.

Sets a max-active-run override for one explicit owner scope.

Resets one owner scope to default inheritance.

Resolves an open interrupt and schedules the next tick or durable wake.

Clears a non-terminal run's poison state and schedules it immediately.

Saves one effective, content-addressed graph version.

Starts a run from a previously saved graph reference.

Functions

__using__(default_opts)

(macro)

Defines a host runtime module wrapping a named runtime instance:

defmodule MyApp.Docket do
  use Docket, backend: Docket.Postgres, repo: MyApp.Repo
end

The options become immutable configuration for the runtime instance. The host module gets supervision and operational wrappers that call Docket with the module as the runtime instance. When the static configuration selects Docket.Postgres.ClaimPolicy.TenantFair and the declared backend exposes the optional claim-policy administration capability, the host module also gets the five same-named public policy wrappers. That export decision is made from the use Docket options; if a startup override replaces the backend with an incapable backend, those wrappers safely return %Docket.Error{type: :unsupported_capability}.

await_run(runtime, run_id, opts \\ [])

Polls durable operational state until waiting, terminal, poisoned, or timeout.

:timeout is required and expressed in milliseconds. :poll_interval defaults to 50 milliseconds.

cancel_run(runtime, run_id, opts \\ [])

Cancels a durable active run and confirms the committed terminal state.

child_spec(opts)

Child spec integration point: {Docket, name: MyRuntime, backend: ...} starts a Docket.Runtime.Supervisor tree.

drain_runs(runtime, opts \\ [])

Synchronously claims and drains due durable runs in a backend testing mode.

fetch_claim_policy_default(runtime)

@spec fetch_claim_policy_default(term()) ::
  {:ok, Docket.ClaimPolicy.t()} | {:error, term()}

Fetches the persisted max-active-run default for a configured runtime.

An unset persisted default is returned as a Docket.ClaimPolicy with max_active_runs: nil and version: 0.

fetch_event(runtime, run_id, seq, opts \\ [])

@spec fetch_event(term(), String.t(), pos_integer(), keyword()) ::
  {:ok, Docket.Event.t()} | {:error, term()}

Reads one retained durable event by its positive sequence number.

A missing or pruned sequence, an unknown run, and a wrong tenant all return {:error, :not_found}.

fetch_graph(runtime, graph_ref, opts \\ [])

@spec fetch_graph(term(), Docket.GraphRef.t(), keyword()) ::
  {:ok, Docket.Graph.t()} | {:error, term()}

Reads the exact effective graph selected by a Docket.GraphRef.

A reference is relative to the resolved tenant owner scope. Equal references may be saved independently by different tenants; possession of a reference never bypasses tenant isolation. An unknown or differently-owned reference returns {:error, :not_found}.

fetch_latest_event(runtime, run_id, opts \\ [])

@spec fetch_latest_event(term(), String.t(), keyword()) ::
  {:ok, Docket.Event.t() | nil} | {:error, term()}

Reads the latest retained durable event for a run.

A visible run whose complete event history has been pruned returns {:ok, nil}. An unknown run and a wrong tenant return {:error, :not_found}.

fetch_latest_graph_ref(runtime, graph_id, opts \\ [])

@spec fetch_latest_graph_ref(term(), String.t(), keyword()) ::
  {:ok, Docket.GraphRef.t()} | {:error, term()}

Reads the reference for the newest distinct version of a graph ID.

Latest is scoped to the resolved tenant and uses the same durable ordering as list_graph_versions/3. Re-saving an existing version is idempotent and does not move it forward in that order.

fetch_latest_run(runtime, opts \\ [])

@spec fetch_latest_run(
  term(),
  keyword()
) :: {:ok, Docket.RunSummary.t()} | {:error, term()}

Fetches the newest run summary matching the supplied tenant scope and optional graph/status filters.

Returns {:error, :not_found} when the scoped query has no matches.

fetch_run(runtime, run_id, opts \\ [])

Reads the last committed durable Docket.Run.

inspect_claim_policy(runtime, owner_scope)

@spec inspect_claim_policy(term(), Docket.Backend.owner_scope()) ::
  {:ok, Docket.ClaimPolicyInfo.t()} | {:error, term()}

Inspects one owner scope's effective cap and aggregate admission state.

The returned Docket.ClaimPolicyInfo contains token-free counts for due queued, admitted-ready, and admitted-claimed logical runs, plus cap debt. An unset persisted default returns {:error, :not_initialized}. A persisted cap under an inactive engine returns {:error, :inactive_engine}.

inspect_run(runtime, run_id, opts \\ [])

Reads a durable run plus token-free operational state.

list_events(runtime, run_id, opts \\ [])

Reads a page of retained durable events for a run.

Events come back in ascending sequence order, restricted to sequences greater than :after_seq (default 0) and limited by :limit (default 250, an integer in 1..1000). Sequence gaps from persistence filtering and retention pruning are normal, so pages are not promised contiguous. The returned Docket.EventPage carries the retention bounds and the run's latest committed event sequence observed from the same snapshot.

Invalid options return {:error, %Docket.Error{type: :invalid_options}} without reaching storage. A wrong tenant and an unknown run both return {:error, :not_found}.

{:ok, page} = MyApp.Docket.list_events("run-123", after_seq: 10, limit: 50)
page.events

list_graph_versions(runtime, graph_id, opts \\ [])

@spec list_graph_versions(term(), String.t(), keyword()) ::
  {:ok, Docket.GraphVersionPage.t()} | {:error, term()}

Lists one graph ID's saved versions newest first under the resolved tenant.

:before is an exclusive cursor returned as next_before by the preceding page. :limit defaults to 100 and must be in 1..1000. An unknown graph ID returns a successful empty Docket.GraphVersionPage.

list_runs(runtime, opts \\ [])

@spec list_runs(
  term(),
  keyword()
) :: {:ok, Docket.RunPage.t()} | {:error, term()}

Lists durable runs visible to the resolved tenant scope.

Runs are returned as lightweight Docket.RunSummary values in newest-first order by the immutable {started_at, run_id} key. :before accepts the previous page's next_before cursor. Optional filters are :status (one durable status or a non-empty list), :graph_id, and :graph_hash. :limit defaults to 100 and must be in 1..1000.

An empty result is a successful empty Docket.RunPage. Under tenant_mode: :required, :tenant_id is mandatory and is always an access scope, never an optional filter.

put_claim_policy_default(runtime, max_active_runs, opts \\ [])

@spec put_claim_policy_default(term(), Docket.ClaimPolicy.cap(), keyword()) ::
  {:ok, Docket.ClaimPolicy.t()} | {:error, term()}

Initializes or updates the persisted max-active-run default.

max_active_runs must be an integer in 1..2_147_483_647. Pass expected_version: version for compare-and-set behavior. A mismatch returns {:error, :stale} without changing policy state.

put_claim_policy_override(runtime, owner_scope, max_active_runs, opts \\ [])

@spec put_claim_policy_override(
  term(),
  Docket.Backend.owner_scope(),
  Docket.ClaimPolicy.cap(),
  keyword()
) :: {:ok, Docket.ClaimPolicy.t()} | {:error, term()}

Sets a max-active-run override for one explicit owner scope.

owner_scope is :tenantless or {:tenant, non_empty_binary}. Pass expected_version: 0 to create an override with compare-and-set behavior.

reset_claim_policy_override(runtime, owner_scope, opts \\ [])

@spec reset_claim_policy_override(term(), Docket.Backend.owner_scope(), keyword()) ::
  {:ok, Docket.ClaimPolicy.t()} | {:error, term()}

Resets one owner scope to default inheritance.

Pass expected_version: version for compare-and-set behavior. A missing or mismatched partition version returns {:error, :stale}.

resolve_interrupt(runtime, run_id, interrupt_id, value, opts \\ [])

Resolves an open interrupt and schedules the next tick or durable wake.

Unknown or already-resolved interrupts return {:error, %Docket.Error{type: :not_found}}. The stored effective graph is loaded and compiled on the executing node without injecting new defaults, the pure mutation and its events commit atomically, and tenant scope is enforced before storage access. Authorization remains host-owned.

retry_poisoned_run(runtime, run_id, opts \\ [])

Clears a non-terminal run's poison state and schedules it immediately.

save_graph(runtime, graph, opts \\ [])

Saves one effective, content-addressed graph version.

Publication snapshots each node implementation's configuration schema once and materializes its defaults into the durable graph before hashing. Storage keeps that effective graph; execution loads and compiles it on the node that performs the work.

start_run(runtime, graph_ref, input, opts \\ [])

Starts a run from a previously saved graph reference.

The effective graph is fetched, validated against local node contracts, and compiled without injecting defaults introduced after publication. The initialized run and assigned events then commit atomically. Durable checkpoint observers run only after that commit; starting a run never publishes or changes a graph document.