| | | 1 | | namespace AsyncResponse; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Thrown when a durable-flow wake-up could not acquire the execution lease and found no proof |
| | | 5 | | /// that the run is executing on a live worker. |
| | | 6 | | /// <para> |
| | | 7 | | /// A held lease is not proof of a live holder: the holder may have died inside its unexpired |
| | | 8 | | /// lease window, and the message being handled is then very likely the run's only remaining |
| | | 9 | | /// wake-up. The engine acknowledges a contended wake-up as a duplicate only on evidence — the |
| | | 10 | | /// lease was renewed or taken over while the wake-up waited (see |
| | | 11 | | /// <see cref="IFlowStateStore.ObserveLeaseAsync"/>) — never because its <em>own</em> configured |
| | | 12 | | /// lease window elapsed: the lease in the way may have been issued by another deployment with a |
| | | 13 | | /// longer <c>ExecutionLeaseDuration</c>, and acknowledging on local configuration stranded those |
| | | 14 | | /// runs as <see cref="FlowRunStatus.Running"/> forever. |
| | | 15 | | /// </para> |
| | | 16 | | /// <para> |
| | | 17 | | /// Throwing keeps the wake-up with the worker transport, whose retry policy redelivers it and |
| | | 18 | | /// whose dead-letter queue is the alarm if the contention never resolves. |
| | | 19 | | /// </para> |
| | | 20 | | /// </summary> |
| | | 21 | | public sealed class DurableFlowLeaseContendedException : InvalidOperationException |
| | | 22 | | { |
| | | 23 | | /// <summary>Creates the exception for <paramref name="flowId"/>.</summary> |
| | | 24 | | public DurableFlowLeaseContendedException(string flowId, string reason) |
| | 14 | 25 | | : base( |
| | 14 | 26 | | $"Durable flow '{flowId}' wake-up could not acquire the execution lease and cannot prove the run is executin |
| | 14 | 27 | | "The wake-up is not acknowledged; the worker transport redelivers it.") |
| | | 28 | | { |
| | 14 | 29 | | FlowId = flowId; |
| | 14 | 30 | | Reason = reason; |
| | 14 | 31 | | } |
| | | 32 | | |
| | | 33 | | /// <summary>The flow whose execution lease stayed contended.</summary> |
| | 4 | 34 | | public string FlowId { get; } |
| | | 35 | | |
| | | 36 | | /// <summary>Why the contention could not be resolved, for operator triage.</summary> |
| | 18 | 37 | | public string Reason { get; } |
| | | 38 | | } |