Table of Contents

Interface IFlowRunControlStore

Namespace
FlowOrchestrator.Core.Storage
Assembly
FlowOrchestrator.Core.dll

Persistence contract for run-level control signals: cancellation, timeout, and idempotency. Decoupled from IFlowRunStore so control records can be written before the run is committed.

public interface IFlowRunControlStore

Methods

ConfigureRunAsync(Guid, Guid, string, string?, DateTimeOffset?)

Persists the control record for a new run, including an optional idempotency key and an absolute timeout deadline.

Task ConfigureRunAsync(Guid runId, Guid flowId, string triggerKey, string? idempotencyKey, DateTimeOffset? timeoutAtUtc)

Parameters

runId Guid
flowId Guid
triggerKey string
idempotencyKey string
timeoutAtUtc DateTimeOffset?

Returns

Task

ExtendDeadlineAsync(Guid, DateTimeOffset?)

Grants a run a fresh execution window: sets TimeoutAtUtc to newTimeoutAtUtc (or clears the deadline when null) and un-latches any timeout-induced termination — clears TimedOutAtUtc and the cancellation fields that MarkTimedOutAsync(Guid, string?) set. A genuine user cancellation (recorded via RequestCancelAsync(Guid, string?) while the run had not timed out) is preserved.

Task<bool> ExtendDeadlineAsync(Guid runId, DateTimeOffset? newTimeoutAtUtc)

Parameters

runId Guid

The run whose deadline is being refreshed.

newTimeoutAtUtc DateTimeOffset?

The new absolute deadline, or null to leave the run without a timeout bound.

Returns

Task<bool>

true if the record was found and updated; false otherwise.

Remarks

Called by FlowOrchestratorEngine.RetryStepAsync before re-dispatch so a step retried after the run's deadline lapsed can actually re-execute instead of being skipped by the termination gate. Default implementation is a no-op returning false so existing custom IFlowRunControlStore implementations continue to compile.

FindRunIdByIdempotencyKeyAsync(Guid, string, string)

Looks up an existing run that was started with the given idempotency key. Returns the RunId of the existing run, or null if none exists.

Task<Guid?> FindRunIdByIdempotencyKeyAsync(Guid flowId, string triggerKey, string idempotencyKey)

Parameters

flowId Guid
triggerKey string
idempotencyKey string

Returns

Task<Guid?>

GetRunControlAsync(Guid)

Returns the control record for the given run, or null if not found.

Task<FlowRunControlRecord?> GetRunControlAsync(Guid runId)

Parameters

runId Guid

Returns

Task<FlowRunControlRecord>

MarkTimedOutAsync(Guid, string?)

Marks the run as timed out.

Task<bool> MarkTimedOutAsync(Guid runId, string? reason)

Parameters

runId Guid
reason string

Returns

Task<bool>

true if the record was found and updated; false otherwise.

Remarks

Invoked from two places: lazily by the engine when a step is dispatched after the deadline has passed, and proactively by the periodic timeout-enforcement hosted service (FlowTimeoutEnforcementHostedService). Also sets the cancellation latch so in-flight steps short-circuit on their next dispatch — a fresh execution window can be granted afterwards via ExtendDeadlineAsync(Guid, DateTimeOffset?).

RequestCancelAsync(Guid, string?)

Marks a cancellation request for the run. Steps check this flag before executing.

Task<bool> RequestCancelAsync(Guid runId, string? reason)

Parameters

runId Guid
reason string

Returns

Task<bool>

true if the record was found and updated; false otherwise.

TryRegisterIdempotencyKeyAsync(Guid, string, string, Guid)

Atomically registers an idempotency key for the given run.

Task<bool> TryRegisterIdempotencyKeyAsync(Guid flowId, string triggerKey, string idempotencyKey, Guid runId)

Parameters

flowId Guid
triggerKey string
idempotencyKey string
runId Guid

Returns

Task<bool>

true if the key was registered by this call; false if a record with this key already existed (duplicate trigger).