Docket.Run (docket v0.1.0)

Copy Markdown View Source

Durable execution state for one graph run.

Docket creates a run when execution starts, and the configured backend stores each committed transition. Applications may read the top-level fields (id, graph_id, graph_hash, status, step, input, output, and the timestamps), but should not interpret, pattern match, mutate, or rebuild Docket-owned execution internals such as channels, interrupts, the changed-channel set, or the active-superstep state (active_tasks, pending_writes, and timers).

Status

The durable/public status vocabulary is exactly five values:

  • :running - autonomous graph execution can proceed. This one value covers ready, claimed, timer-scheduled, budget-yielded, and retry-backoff positions; queue position is derived from schedule, claim, and active-superstep facts, never stored as extra statuses.
  • :waiting - open interrupts and nothing else can proceed; only an external graph mutation resumes the run.
  • :done / :failed / :cancelled - terminal and absorbing.

:created is a private initialization sentinel: a built-but-never initialized run consumed by the runtime's init barrier. It exists only before that transition commits, is not cancellable, and is rejected by durable storage.

Status describes graph execution state, not Runtime process liveness and not operational health - see Docket.RunInfo for the latter.

Transitions

created -> running                                    (initialization)
running -> running | waiting | done | failed | cancelled
waiting -> running | cancelled

Terminal statuses are absorbing. A retryable node failure stays :running with a future wake; only permanent or exhausted graph failure becomes :failed.

Active superstep

Between a retryable node failure and the superstep's update barrier, the run durably encodes the superstep in flight: active_tasks holds the parked next attempt of each still-executing task (stable identity, snapshot, accumulated failures), pending_writes holds completed sibling results that stay invisible to channels until the barrier, and timers holds each parked task's retry deadline. These fields are non-empty only on a :running run and are cleared by the barrier or a terminal commit.

Failure

failure carries the durable Docket.Run.Failure cause of a terminal graph failure. It is present exactly when status is :failed (see validate_failure/1), independently of retained event history.

Summary

Types

Durable/public graph status.

Any graph status, including the private :created sentinel.

t()

Functions

Returns true for the five durable/public graph statuses and false for the private :created sentinel (and anything else).

Returns the five durable/public graph statuses.

Returns true when the run has reached a terminal status.

Returns the terminal subset of the durable graph statuses.

Returns true when a run may move from from to to in one committed transition.

Validates that failure is present exactly when the run is :failed.

Types

durable_status()

@type durable_status() :: :running | :waiting | :done | :failed | :cancelled

Durable/public graph status.

status()

@type status() :: :created | durable_status()

Any graph status, including the private :created sentinel.

t()

@type t() :: %Docket.Run{
  active_tasks: %{optional(String.t()) => Docket.Run.TaskState.t()},
  changed_channels: MapSet.t(String.t()),
  channels: %{optional(String.t()) => Docket.Run.ChannelState.t()},
  checkpoint_seq: non_neg_integer(),
  event_seq: non_neg_integer(),
  failure: Docket.Run.Failure.t() | nil,
  finished_at: DateTime.t() | nil,
  graph_hash: String.t() | nil,
  graph_id: String.t(),
  id: String.t(),
  input: map(),
  interrupts: %{optional(String.t()) => Docket.Run.InterruptState.t()},
  metadata: map(),
  output: map() | nil,
  pending_nodes: MapSet.t(String.t()),
  pending_writes: [Docket.Run.PendingWrite.t()],
  started_at: DateTime.t() | nil,
  status: status(),
  step: non_neg_integer(),
  timers: %{optional(String.t()) => Docket.Run.TimerState.t()},
  updated_at: DateTime.t() | nil
}

Functions

durable_status?(status)

@spec durable_status?(term()) :: boolean()

Returns true for the five durable/public graph statuses and false for the private :created sentinel (and anything else).

durable_statuses()

@spec durable_statuses() :: [durable_status()]

Returns the five durable/public graph statuses.

The private :created sentinel is deliberately excluded: it must never be written to durable storage.

terminal?(run)

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

Returns true when the run has reached a terminal status.

terminal_statuses()

@spec terminal_statuses() :: [durable_status()]

Returns the terminal subset of the durable graph statuses.

valid_transition?(arg1, to)

@spec valid_transition?(status(), status()) :: boolean()

Returns true when a run may move from from to to in one committed transition.

Encodes the transition matrix from the module documentation: :created -> :running is the initialization edge, :running may recommit itself or reach any other durable status, :waiting may only resume to :running or be cancelled, and terminal statuses are absorbing.

validate_failure(run)

@spec validate_failure(t()) :: :ok | {:error, Docket.Error.t()}

Validates that failure is present exactly when the run is :failed.

Returns {:error, Docket.Error.t()} for a failed run without a Docket.Run.Failure, any other status carrying one, or a failure value of the wrong type.