Class DefaultResumableRun<S>

java.lang.Object
com.tnsai.reliability.DefaultResumableRun<S>
Type Parameters:
S - state type threaded through the step list
All Implemented Interfaces:
ResumableRun<S,S>

public final class DefaultResumableRun<S> extends Object implements ResumableRun<S,S>
Default ResumableRun implementation (TNS-299). Drives a fixed list of DefaultResumableRun.Steps through CheckpointStore, IdempotencyStore (TNS-224), and ProgressSink.

Step model

Each step is a UnaryOperator over a typed state S. The run starts with an input state, threads it through the step list, and returns the terminal state. Steps marked DefaultResumableRun.Step.sideEffecting consult the idempotency store before running so a retry never double-executes a write — the previous stored result is replayed instead.

Crash recovery

After every successful step the orchestrator persists a Checkpoint carrying the post-step state. If the JVM dies mid-run, calling resume(String) with the same runId loads the latest checkpoint and continues from the next step.

Cost ceiling

DefaultResumableRun.Builder.costMonitor is optional. When provided AND RunConfig.costCeilingUSD is set, the orchestrator queries it before every step; if cumulative spend has reached the ceiling, the run aborts with AbortReason.BUDGET_EXHAUSTED after saving a final checkpoint (so the consumer can resume on a higher ceiling).

Concurrency

One instance handles many concurrent runs. execute(S, com.tnsai.reliability.RunConfig) / resume(java.lang.String) / abort(java.lang.String, com.tnsai.reliability.AbortReason) are safe to call concurrently from different threads, each owning its own run id.
Since:
0.10.0 (TNS-299)
  • Method Details

    • builder

      public static <S> DefaultResumableRun.Builder<S> builder()
    • execute

      public Outcome<S> execute(S input, RunConfig config)
      Description copied from interface: ResumableRun
      Start a new run. The orchestrator mints a fresh run id, walks the step list, and returns a terminal Outcome.
      Specified by:
      execute in interface ResumableRun<S,S>
      Parameters:
      input - initial input handed to the first step
      config - execution-time policies; bounds duration / retries / cost / progress timeout
      Returns:
      one of the four Outcome variants — never null
    • resume

      public Outcome<S> resume(String runId)
      Description copied from interface: ResumableRun
      Pick up a paused run from its latest checkpoint. The orchestrator loads the checkpoint via CheckpointStore.latest(java.lang.String), restores step state, and continues from the next step.

      If no checkpoint exists for runId, the implementation returns Outcome.Failed with a clear "no such run" message rather than starting a fresh one — confusing one for the other was the bug pattern this primitive is supposed to prevent.

      Specified by:
      resume in interface ResumableRun<S,S>
    • abort

      public void abort(String runId, AbortReason reason)
      Description copied from interface: ResumableRun
      Stop a run that's currently in flight. The orchestrator transitions to Outcome.Aborted at the next step boundary; already-running step bodies are not interrupted, so abort is cooperative — designed for "graceful shutdown by the next safe point" rather than mid-call cancellation.

      Calling abort on a run id that isn't in flight is a no-op (already terminated runs ignore the request).

      Specified by:
      abort in interface ResumableRun<S,S>