Versioned definition for a precise, asynchronous operational procedure.
A Work owns no process and receives no open goal. Its callbacks are short, deterministic reducers; registered operations run separately through the shared operational runtime.
defmodule MyApp.ReadPages do
use Spectre.Work,
id: :read_pages,
version: 1,
input: :map,
state: :map,
update: :map,
budget: [steps: 500, attempts: 750]
operation :fetch_page, {MyApp.Pages, :fetch},
input: :map,
output: :map,
side_effect: :idempotent,
retry: [max_attempts: 3]
@impl true
def init(input, _context), do: {:ok, %{queue: input.urls, pages: []}}
@impl true
def next(%{queue: [url | _]}, _context),
do: run(:fetch_page, %{url: url}, phase: :reading)
@impl true
def apply_result(state, _request, result, _context) do
[_url | rest] = state.queue
{:ok, %{state | queue: rest, pages: [result.value | state.pages]}}
end
@impl true
def complete(%{queue: []} = state, _context), do: complete(Enum.reverse(state.pages))
def complete(_state, _context), do: :continue
end
Summary
Functions
Builds a declared human blocker.
Builds successful deterministic completion.
Builds a terminal failure decision.
Registers a stable operation in this Work's closed catalog.
Registers a stable executor and its validation/lifecycle contract.
Builds the next operation request.
Allows one operation from the Agent's immutable application registry.
Builds a wait boundary.
Functions
Builds a declared human blocker.
Builds successful deterministic completion.
Builds a terminal failure decision.
Registers a stable operation in this Work's closed catalog.
Registers a stable executor and its validation/lifecycle contract.
@spec run(atom() | String.t(), term(), keyword()) :: {:run, Spectre.Operation.Request.t()}
Builds the next operation request.
Allows one operation from the Agent's immutable application registry.
@spec wait( atom(), keyword() ) :: {:wait, Spectre.Operation.Wait.t()}
Builds a wait boundary.