Method ApplyAsync
ApplyAsync(JobTransition, CancellationToken)
Applies an engine-computed transition atomically behind the fence (§4.2.3); false = fence rejected, nothing changed.
public ValueTask<bool> ApplyAsync(JobTransition transition, CancellationToken ct)
Parameters
transitionJobTransitionctCancellationToken
Returns
Remarks
Fence: State == Processing && WorkerId == ExpectedWorkerId && Attempt
== ExpectedAttempt. Effects (all-or-nothing): target state with field effects
(terminal ⇒ FinishedAt set, WorkerId/LeaseUntil cleared, idempotency key released from
its uniqueness scope — the field is retained; Failed ⇒ DueAt/LastError/Failures set,
WorkerId/LeaseUntil cleared; Enqueued release ⇒ WorkerId/LeaseUntil cleared);
Enqueue inserts (EnqueueAsync semantics, this transition's
key release visible to them); one-level continuation activation; transitive continuation
cancellation; and Checkpoint, the workflow instance update.
Checkpoint ordering. The fence is evaluated first: if it rejects, the call returns false and no checkpoint is attempted — a worker that no longer owns the job has no business advancing the instance. If the fence holds but ExpectedRevision does not match the stored revision (or the instance is missing), the whole transition rolls back and MillraceConcurrencyException is thrown: the caller reloads and retries the merge. The two outcomes stay distinguishable because they demand different reactions.
Exceptions
- MillraceConcurrencyException
A checkpoint was supplied and its revision was stale, or its instance does not exist. Nothing changed.