Skip to content
Archived Docsv26.7.1

Await Unit Runtime

Await units are the durable suspend/resume model for kind: await steps. The unit is the interaction boundary TPF owns: it records what was dispatched, what completion is required, and what payload should be replayed when the owning execution resumes.

This guide is implementation-facing. Application-facing design guidance lives in Await Boundaries. Runtime setup lives in Await runtime setup.

For the longer-term orchestration boundary that can move await units out of each app-hosted orchestrator, see Durable Coordinator. For the immutable queue-async model that treats await completion and checkpoint handoff as the same boundary-admission shape, see Immutable Segment And Boundary Model.

Guide Pages

  1. Model explains the durable records and cardinality semantics.
  2. Immutable Boundaries explains the segment, boundary, fact, and projection model behind queue-async.
  3. Sequences shows unary, stream, aggregate, timeout, and resume flows.
  4. Patterns explains the architectural patterns and why the unit model fixed the design.
  5. Limitations And Debt tracks implementation limitations and follow-up work.

Core Model

The key split is:

  1. AwaitUnitRecord: one durable interaction unit for an authored await step at a specific execution and step index.
  2. AwaitInteractionRecord: one externally visible interaction that can be queried, dispatched, completed, timed out, or correlated by transport.
  3. ExecutionRecord.awaitUnitId: the parked continuation pointer used while the execution is WAITING_EXTERNAL.

AwaitUnitRecord is the current compatibility projection for completion of the authored await boundary. AwaitInteractionRecord is the transport-facing projection. The target queue-async model represents the same behavior as immutable BoundaryUnit and BoundaryInteraction projections derived from appended facts.

In that model, PipelineRunner still runs synchronous step segments. An await step suspends one ExecutionSegment by appending a SegmentSuspended fact. Kafka, webhook, or interaction-api completion appends BoundaryCompletionAdmitted. If a live await session is present, the admitted completion can flow into the active downstream Multi; if not, the same durable facts create continuation segment work.

That continuation is the future beginning of the suspended pipeline. AwaitContinuationPlanner decides whether a completion is still held, releases a scalar resume, dispatches item continuations, records item output, or releases an itemized parent. ScalarAwaitContinuationFlow and ItemizedAwaitContinuationFlow interpret those decisions through the existing projection stores and dispatcher. ItemContinuationClaims is only process-local duplicate suppression; durable truth remains in the stores and immutable ledger facts.

CSV Payments Applied Model

csv-payments applies this model to a Kafka-backed payment-provider boundary:

  1. Process Csv Payments Input expands an input file into a stream of PaymentRecord items.
  2. Await Payment Provider is authored as kind: await with cardinality: ONE_TO_ONE.
  3. Because the await step receives a stream, TPF creates one owning await unit with one item interaction per PaymentRecord.
  4. The Kafka adapter publishes requests to csv-payments.payment.requests; the mock provider publishes completions to csv-payments.payment.results.
  5. Completed item outputs are PaymentStatus union variants. In the live Kafka path, completions are recorded and signalled into the live await session so the approved or unapproved status branch can run as downstream demand accepts it. In the fallback path, the runtime resumes per-item work from durable item continuations.
  6. In the connector-first default path, terminal PaymentOutput records are published by Object Publish rather than by a ProcessCsvPaymentsOutputFileService business step.

The important detail is that CSV does not model the provider as a pipeline step. The provider is an external actor reached through the await transport. The pipeline resumes from admitted PaymentStatus completions.

WAITING_EXTERNAL is still the durable recovery pointer. It is not the live-path release gate when a live await session is active and accepting completions.

Cardinality As Unit Shape

Cardinality defines the unit TPF must durably replay.

Authored cardinalityUnit shapeInteractionsResume input
ONE_TO_ONE on one inputone input, one outputone primary interactionscalar output
ONE_TO_ONE over a streamone unit owning ordered item interactionsone interaction per input itemordered list/stream of completed item outputs
ONE_TO_MANYone input, many output itemsone primary interactionmaterialized output unit replayed as a stream
MANY_TO_ONEmany input items, one outputone primary interaction after input materializationscalar output
MANY_TO_MANYmany input items, many output itemsone primary interaction after input materializationmaterialized output unit replayed as a stream

The unit, not an ad hoc dispatch mode, decides what gets snapshotted and replayed. For aggregate cardinalities, v1 materializes the input and/or output unit. If downstream replay fails halfway through a materialized output unit, TPF restarts replay of that whole output unit. It does not claim exactly-once progress inside the unit.