Skip to content
bitzorcas
中EN

Guide

Running Workflow Instances

Start, complete, reject, withdraw, resubmit, handoff, control, multi-instance, transactions, concurrency, callbacks, and timer failure semantics.

Last updated

Runtime does not merely update CurrentNodeId. It coordinates instance version, execution tokens, tasks, candidates, FlowState, BusinessStatus, activity, timers, cache, and external callbacks. Business code enters through focused ports or Platform commands.

1. Runtime ports

PortOperations
IWorkflowTransitionFlowStart, Complete, Reject, Withdraw, Resubmit
IWorkflowTaskHandoffFlowTransfer, Delegate, AddParticipant
IWorkflowMigrationFlowResetToNode, StartAtNode, TransferApplicant
IWorkflowBatchOperationTerminate, Cancel, Suspend, Resume, Remind, BatchComplete, Priority
IWorkflowQueryProgressView

IRuntimeService is an obsolete compatibility facade.

2. Start

TokenExecutorPersistenceRuntimeApplicationTokenExecutorPersistenceRuntimeApplicationStart with trusted actor and tenantresolve deploymentcreate instance and variablesbegin transactionsave instance and start activityexecute start and following nodescreate executions, tasks, timerscommit
Start matter intake approval
// Actor and tenant come from authenticated server context.
Result<IProcessInstance> started = await transitions.StartAsync(
"matter-intake-approval",
matter.MatterNo,
"MatterIntake",
currentUserId,
currentTenantId,
matter.OfficeId,
new Dictionary<string, object?>
{
// Pass routing facts, not the mutable business aggregate.
["disputeAmount"] = matter.DisputeAmount,
["crossBorder"] = matter.IsCrossBorder
},
cancellationToken);

Start has no IdempotencyKey and does not visibly precheck definitionKey+businessKey. Reconcile after a timeout before retrying.

3. Complete

Completion loads a Pending task, performs Operate permission, loads the pinned definition, and in one transaction advances instance Version, completes the task, handles multi-instance, leaves the node, moves tokens, updates state, and appends activity.

Approve and supply route variables
// Runtime rechecks Pending state and Operate permission before writing.
Result completed = await transitions.CompleteTaskAsync(
taskId,
currentUserId,
"Conflict check cleared; open the matter",
new Dictionary<string, object?>
{
// These values become the snapshot used by the next gateway.
["conflictCleared"] = true,
["engagementLetterSent"] = false
},
cancellationToken);

A duplicate may return TaskNotPending or ConcurrencyConflict rather than the original response.

4. Reject, withdraw, and resubmit

Reject accepts an explicit target or resolves RollbackRule, rebuilds relevant execution/task state, and records the transition. Withdraw uses current-applicant semantics — it maps to ProcessInstanceStatus.Cancelled with BusinessStatus = "Withdraw", from which Resubmit reopens the flow. There is no distinct Withdrawn enum value.

IApplicantResolver can resolve current ownership dynamically and falls back to CurrentApplicantId/StarterId. TransferApplicant updates that snapshot.

5. Handoff

Transfer permanently changes responsibility. Delegate is temporary. AddParticipant adds approvers. These task-focused writes advance instance Version inside the transaction so they conflict with other writes on the same instance.

Transfer a task
// Validate that the successor is an active user in the same tenant.
Result transferred = await handoff.TransferTaskAsync(
taskId,
currentUserId,
successorUserId,
"Coverage while lead counsel is in court",
cancellationToken);

Server enforcement of UserTaskConfig AllowTransfer/AllowDelegate/AllowAddParticipant must be verified; hiding UI controls is insufficient.

6. Control operations

Suspend/Resume, Terminate/Cancel, Reset, and Priority require Manage permission and use optimistic concurrency. BatchComplete is a proxy administrative operation: it atomically marks pending tasks completed and advances versions but intentionally does not move tokens. It is not a batch approval endpoint.

Remind dispatches TaskRemind to pending assignees; notification failures fail the command together with the transition (see section 8), so reminders can no longer silently vanish.

7. Multi-instance and gateways

Parallel multi-instance creates work for each participant; Sequential creates it one at a time. CompletionCondition determines closure. Parallel gateway join scopes by parent execution. Test simultaneous final votes, sibling cancellation, variable merging, nested joins, and inclusive zero-match behavior.

8. Transaction and side effects

IPersistenceStore transaction covers workflow tables and maps concurrency exceptions. Notifications and listeners now ride the failure chain: the platform INotificationChannel writes per-recipient inbox entries plus CAP Outbox rows and throws when any recipient fails; NotificationDispatcher logs and rethrows; EventDispatcher propagates listener exceptions upward — failing and rolling back the whole transition. Approval success and “notification facts persisted” are now the same statement.

IBusinessIntegrationCallback is awaited directly and is not an Outbox. Placement varies by operation and can leave committed workflow state with a failed request or callback. Business synchronization needs idempotency, replay, and reconciliation.

9. Timers

Timer records are created when timed nodes run. JobHost scans Pending. Current order:

Current crash window
var fired = job with { Status = "Fired" };
await store.SaveTimerJobAsync(fired, cancellationToken);
// A crash or action failure here does not restore Pending.
await DispatchJobAsync(job, cancellationToken);

Scanning has no atomic claim either. Add compare-and-swap/lease, attempt, retry time, last error, DLQ, and recovery runbook.

10. Error handling

Distinguish NotFound, Forbidden, InvalidState, TaskNotPending, ConcurrencyConflict, and infrastructure failure. Do not blindly retry all 409 responses; a conflict normally requires a fresh read and user confirmation.

11. Test matrix

  • duplicate business key and disconnected start client;
  • both ORM transaction rollback;
  • complete/reject/terminate races;
  • assignee, candidate, applicant, and Manage permissions;
  • notification and callback failure state;
  • duplicate scan, crash, unknown timer, and failed escalation;
  • parallel and multi-instance convergence;
  • cross-node cache invalidation.

Next: task management

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%