Structure of the workflow state data stored per instance
OptionalcleanupOptional cleanup hook invoked during successful workflow completion.
The orchestrator calls this automatically when a workflow instance:
This executes AFTER final state persistence but BEFORE the completion event is emitted back to the initiator. This ordering ensures the final state is durably saved before cleanup runs, while allowing cleanup logic to complete before the workflow signals completion to external systems.
IMPORTANT: This hook is NOT called when orchestration execution fails (e.g., lock acquisition failure, state persistence failure, handler errors). It only executes for workflows that successfully reach their final state.
Receives the same state transition data as write() to enable intelligent cleanup decisions based on how the workflow completed and what changed in the final step.
This hook enables custom memory management strategies:
Implementations are not required to delete state immediately - they can implement whatever retention/archival strategy suits their operational needs.
Workflow instance identifier (event.subject)
Final workflow state that was just persisted
Previous state before final persistence (null if this was first/only state)
Workflow context (subject, parent subject, source)
Acquires exclusive execution lock for a workflow instance.
Prevents concurrent processing of the same workflow instance across distributed orchestrator instances. The orchestrator acquires this lock before reading/modifying state to ensure only one instance processes events for this workflow at any given time.
Should implement reasonable retries (2-3 attempts) with backoff for transient lock conflicts, then fail fast. Returns false if another instance holds the lock after retries exhausted.
CRITICAL: Should set TTL when acquiring lock (typically 30s-5m based on expected execution duration) to prevent permanent deadlocks if unlock fails.
Workflow instance identifier (event.subject)
Workflow context (subject, parent subject, source)
true if lock acquired successfully, false if lock held by another instance
Retrieves persisted state for a specific workflow instance.
The orchestrator calls this when resuming a workflow to load the context needed to continue from where it previously stopped. Returns null for new workflow instances that have no persisted state yet.
Should implement minimal retries (2-3 attempts) with short backoff for transient failures to avoid blocking event processing. Total operation time should stay under 1 second.
Workflow instance identifier (event.subject)
Workflow context (subject, parent subject, source)
null if no state exists for this workflow instance, T if state found
Releases execution lock for a workflow instance.
Called after the orchestrator finishes processing an event and persisting state. Can retry a few times on transient failures but should not block execution - the TTL-based expiry ensures eventual recovery even if unlock fails.
The "be tolerant on release" philosophy means unlock failures don't cascade into workflow failures. The lock will auto-expire via TTL, allowing the workflow to resume after the timeout period.
Workflow instance identifier (event.subject)
Workflow context (subject, parent subject, source)
true if unlocked successfully, false if unlock failed (non-critical)
Persists updated state for a specific workflow instance.
Called after the orchestrator processes an event and needs to save the workflow's current context before terminating. The next event for this workflow will load this saved state to resume execution.
Should fail fast without retries - if persistence fails, the orchestrator must know immediately to avoid state inconsistency. The caller handles failures through retry mechanisms or dead letter queues.
Workflow instance identifier (event.subject)
Current workflow state to persist
Previous state snapshot (can be used for compare-and-swap or audit trails)
Workflow context (subject, parent subject, source)
Manages workflow instance state with optimistic locking for orchestration handlers.
Each workflow execution has a unique identifier (event.subject) that remains constant throughout its entire lifecycle. This interface uses that subject as the key for all state operations, enabling multiple concurrent executions of the same orchestrator to maintain isolated state.
Implements "fail fast on acquire, be tolerant on release" locking philosophy: