< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: AsyncResponse.IFlowStateStore
Assembly: AsyncResponse.Abstractions
File(s): /_/src/AsyncResponse.Abstractions/IFlowStateStore.cs
Line coverage
100%
Covered lines: 2
Uncovered lines: 0
Coverable lines: 2
Total lines: 91
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ValidateCreate(...)100%11100%
ObserveLeaseAsync(...)100%11100%

File(s)

/_/src/AsyncResponse.Abstractions/IFlowStateStore.cs

#LineLine coverage
 1namespace AsyncResponse;
 2
 3/// <summary>
 4/// Persists durable-flow ledgers with the atomic operations required for safe multi-replica
 5/// execution. Implementations must provide insert-if-absent creation, revision-checked updates,
 6/// and renewable owner-fenced execution leases.
 7/// </summary>
 8public interface IFlowStateStore
 9{
 10    /// <summary>
 11    /// Checks deterministic creation constraints, including the serialized state-size budget,
 12    /// without writing state or contacting external infrastructure. The starter calls this before
 13    /// publishing its start job. Implementations must still validate actual writes; this is not a
 14    /// reservation. The default is a no-op for compatibility with application-owned stores.
 15    /// </summary>
 16    /// <exception cref="FlowStateTooLargeException">The initial state exceeds the store's budget.</exception>
 38017    void ValidateCreate(string flowId, FlowState state, TimeSpan ttl) { }
 18
 19    /// <summary>Atomically creates a new flow ledger; returns false when the id already exists.</summary>
 20    Task<bool> TryCreateAsync(
 21        string flowId,
 22        FlowState state,
 23        TimeSpan ttl,
 24        CancellationToken cancellationToken = default);
 25
 26    /// <summary>
 27    /// Loads the state of one flow run, or <c>null</c> when the run is genuinely gone — unknown,
 28    /// pruned, or expired. A row that exists but cannot be interpreted — malformed JSON, an
 29    /// unknown schema version, a revision inside the JSON that disagrees with the stored one, a
 30    /// flow id inside the JSON that is not the key — is <em>not</em> absence and must throw
 31    /// <see cref="FlowStateUnreadableException"/>: callers acknowledge a wake-up on <c>null</c>,
 32    /// so reporting a live-but-unreadable ledger that way strands the run.
 33    /// </summary>
 34    /// <exception cref="FlowStateUnreadableException">The ledger exists but is uninterpretable or inconsistent.</except
 35    Task<FlowState?> LoadAsync(string flowId, CancellationToken cancellationToken = default);
 36
 37    /// <summary>
 38    /// Atomically replaces a ledger when its stored revision matches <paramref name="expectedRevision"/>.
 39    /// When <paramref name="leaseId"/> is supplied, that same unexpired execution lease must own
 40    /// the ledger. The supplied state's revision is the new revision to persist.
 41    /// </summary>
 42    Task<bool> TryUpdateAsync(
 43        string flowId,
 44        FlowState state,
 45        long expectedRevision,
 46        TimeSpan ttl,
 47        string? leaseId = null,
 48        CancellationToken cancellationToken = default);
 49
 50    /// <summary>Atomically acquires an expired or unowned execution lease.</summary>
 51    Task<bool> TryAcquireLeaseAsync(
 52        string flowId,
 53        string leaseId,
 54        TimeSpan leaseDuration,
 55        CancellationToken cancellationToken = default);
 56
 57    /// <summary>Renews an unexpired lease owned by <paramref name="leaseId"/>.</summary>
 58    Task<bool> TryRenewLeaseAsync(
 59        string flowId,
 60        string leaseId,
 61        TimeSpan leaseDuration,
 62        CancellationToken cancellationToken = default);
 63
 64    /// <summary>Releases the lease when it is still owned by <paramref name="leaseId"/>.</summary>
 65    Task ReleaseLeaseAsync(
 66        string flowId,
 67        string leaseId,
 68        CancellationToken cancellationToken = default);
 69
 70    /// <summary>
 71    /// Reports the execution lease currently persisted for <paramref name="flowId"/> — the raw
 72    /// owner and expiry, without judging whether it has lapsed. Returns
 73    /// <see cref="FlowLeaseObservation.Unheld"/> when no lease is held (or the ledger is absent),
 74    /// and <c>null</c> when this store cannot report leases at all, which is the default for
 75    /// compatibility with application-owned stores.
 76    /// <para>
 77    /// A wake-up that finds the lease held uses this to tell a live holder from a dead one: a
 78    /// lease whose owner or expiry changes while the wake-up waits was acquired or renewed by a
 79    /// live worker, so the wake-up is a duplicate; a lease that never changes belongs to a dead
 80    /// holder and is waited out to its <em>persisted</em> expiry, whatever lease duration issued
 81    /// it. A store that returns <c>null</c> gives the engine no such evidence, so a wake-up that
 82    /// cannot acquire the lease within its own lease window is never acknowledged: it fails with
 83    /// <see cref="DurableFlowLeaseContendedException"/> and the worker transport redelivers it.
 84    /// </para>
 85    /// </summary>
 86    Task<FlowLeaseObservation?> ObserveLeaseAsync(string flowId, CancellationToken cancellationToken = default)
 687        => Task.FromResult<FlowLeaseObservation?>(null);
 88
 89    /// <summary>Deletes the state of one flow run; <c>true</c> when an entry was removed.</summary>
 90    Task<bool> TryDeleteAsync(string flowId, CancellationToken cancellationToken = default);
 91}