.NET API
IWorkflowResponseStore
Tracon.Abstractions.dllWhere the answers to a workflow’s pending human requests are recorded: which run answered which request of which run, who answered, and whether the single answer a WorkflowResponseMode.SingleAnswer workflow allows is already taken.
public interface IWorkflowResponseStoreRemarks
Section titled “Remarks”The store keeps the decision, not its content: a record carries a SHA-256 of the answer, never the answer itself. The request is still read from the waiting run’s RunEventType.WorkflowRequest event.
Tenant behavior. Reads and updates use the ambient tenant, read from
ITenantContext: IWorkflowResponseStore.FindClaimAsync, IWorkflowResponseStore.ReplaceAsync (the record
it abandons), IWorkflowResponseStore.MarkDeliveredAsync, IWorkflowResponseStore.ListBySourceRunAsync and
IWorkflowResponseStore.GetAsync see only the caller’s tenant. A write uses the expected tenant the
record carries (WorkflowResponseRecord.TenantId). Two tenants can hold a claim
with the same scope and request id without seeing each other.
DI lifetime. Registered as a singleton with TryAdd; a consumer’s own
registration wins, and each SQL provider replaces the in-memory default. An implementation
must be safe under concurrent calls: two answers to one request arrive together by design.
Delivery. No delivery guarantee applies: every call completes or throws before it returns, and nothing is sent later. The respond endpoint refuses an answer whose record cannot be written; the engine’s IWorkflowResponseStore.MarkDeliveredAsync call is best-effort and only logged when it fails.
A record is deleted only with its source run: a SQL store ties it to the run with a cascading foreign key, and a data subject erasure that removes the source run removes its records too. No retention target deletes runs, so the records of an installation grow until such an erasure; plan for that the way you plan for the run history itself.
Methods
Section titled “Methods”AddAsync(WorkflowResponseRecord, CancellationToken)
Section titled “ AddAsync(WorkflowResponseRecord, CancellationToken)”Records an answer. When the record carries a WorkflowResponseRecord.ClaimScope, it is written only if no other active record holds the same scope and request id.
ValueTask<WorkflowResponseClaim> AddAsync(WorkflowResponseRecord record, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”record WorkflowResponseRecord
The answer to record. WorkflowResponseRecord.Status must be WorkflowResponseStatus.Accepted and WorkflowResponseRecord.TenantId must be set.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<WorkflowResponseClaim>
WorkflowResponseClaim.Claimed is true when the record was written. It is false when another active record already holds the claim; WorkflowResponseClaim.Existing is that record.
Remarks
Section titled “Remarks”Two concurrent writes with the same claim are decided by the store, atomically: exactly one of them is written. A record without a claim scope is always written.
FindClaimAsync(string, string, CancellationToken)
Section titled “ FindClaimAsync(string, string, CancellationToken)”Finds the active record that holds a claim.
ValueTask<WorkflowResponseRecord?> FindClaimAsync(string claimScope, string requestId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”claimScope string
The claim scope (the execution session of the waiting run).
requestId string
The request id.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<WorkflowResponseRecord?>
The record, or null when no record of the caller’s tenant that is not WorkflowResponseStatus.Abandoned holds the claim.
GetAsync(Guid, CancellationToken)
Section titled “ GetAsync(Guid, CancellationToken)”Returns the record of one answering run.
ValueTask<WorkflowResponseRecord?> GetAsync(Guid responseRunId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”responseRunId Guid
The run that answered.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<WorkflowResponseRecord?>
The record, or null when it is not found in the caller’s tenant.
ListBySourceRunAsync(Guid, CancellationToken)
Section titled “ ListBySourceRunAsync(Guid, CancellationToken)”Lists every answer given to a run’s requests, oldest first.
ValueTask<IReadOnlyList<WorkflowResponseRecord>> ListBySourceRunAsync(Guid sourceRunId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”sourceRunId Guid
The run that waited for the answers.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<IReadOnlyList<WorkflowResponseRecord>>
The records of the caller’s tenant, ordered by WorkflowResponseRecord.RespondedAt.
MarkDeliveredAsync(Guid, CancellationToken)
Section titled “ MarkDeliveredAsync(Guid, CancellationToken)”Records that the workflow received the answer: an WorkflowResponseStatus.Accepted record becomes WorkflowResponseStatus.Delivered.
ValueTask MarkDeliveredAsync(Guid responseRunId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”responseRunId Guid
The run that delivered the answer.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The completion task.
Remarks
Section titled “Remarks”Does nothing when no record of the caller’s tenant has this run id, or when the record is no longer WorkflowResponseStatus.Accepted.
ReplaceAsync(Guid, WorkflowResponseRecord, CancellationToken)
Section titled “ ReplaceAsync(Guid, WorkflowResponseRecord, CancellationToken)”Abandons an active record and writes the record of the run that replaces it, as one atomic step.
ValueTask<bool> ReplaceAsync(Guid abandonedResponseRunId, WorkflowResponseRecord replacement, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”abandonedResponseRunId Guid
The run id of the record to abandon.
replacement WorkflowResponseRecord
The record that takes over the claim. WorkflowResponseRecord.Status must be WorkflowResponseStatus.Accepted.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”true when the record was abandoned and replacement written;
false when the record is not found in the caller’s tenant or is already
WorkflowResponseStatus.Abandoned, in which case nothing is written.
Remarks
Section titled “Remarks”Two concurrent calls that abandon the same record are decided by the store: one returns true, the other false.