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

Information
Class: AsyncResponse.RecoveryState
Assembly: AsyncResponse.Abstractions
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/AsyncResponse.Abstractions/RecoveryState.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 99
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
.ctor()100%11100%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/AsyncResponse.Abstractions/RecoveryState.cs

#LineLine coverage
 1using System.Text.Json.Serialization;
 2
 3namespace AsyncResponse;
 4
 5/// <summary>
 6/// Per-correlation recovery state, stored by the response channel when a waiter registers.
 7/// With a durable store (for example Redis) it outlives the in-memory waiter, so a response that
 8/// arrives after the waiter died (e.g. a redeploy dropped the process) can still be routed: the
 9/// lost-subscriber dispatcher asks the payload's
 10/// <see cref="IAsyncResponsePayload.ShouldResumeOnRecovery"/> and invokes
 11/// <see cref="ResumeCallback"/> or <see cref="FailureCallback"/>.
 12/// <para>
 13/// <b>Contract warning:</b> instances are serialized into the backing store (e.g. Redis) and
 14/// must remain readable across deployments. Treat property names as a wire contract — additive
 15/// changes only. The <see cref="SchemaVersion"/> stamp lets the loader reject (rather than silently
 16/// misinterpret) entries written by an incompatible schema — see
 17/// <see cref="RecoveryStateSchema"/>.
 18/// </para>
 19/// </summary>
 20public sealed class RecoveryState
 21{
 22    /// <summary>
 23    /// The wire schema version this entry was written with. New entries are always stamped with
 24    /// <see cref="RecoveryStateSchema.Current"/>. The property is required on the wire; a missing or
 25    /// unsupported version is rejected so an incompatible writer cannot silently misroute a
 26    /// recovery path.
 27    /// </summary>
 28    [JsonRequired]
 329    public int SchemaVersion { get; set; } = RecoveryStateSchema.Current;
 30
 31    /// <summary>
 32    /// Per-waiter registration id. Multiple recoverable waiters may share one correlation id; this
 33    /// id lets normal waiter cleanup remove only its own registration while lost-subscriber recovery
 34    /// can fan out to every stored registration for the correlation id.
 35    /// </summary>
 36    public Guid RegistrationId { get; set; }
 37
 38    /// <summary>
 39    /// Invoked when a response payload whose
 40    /// <see cref="IAsyncResponsePayload.ShouldResumeOnRecovery"/> returns <c>true</c> arrives with
 41    /// no live subscriber. Typically resumes or re-registers the owning flow.
 42    /// </summary>
 43    public ReflectionCallDto? ResumeCallback { get; set; }
 44
 45    /// <summary>
 46    /// Invoked when an exception envelope — or a payload whose
 47    /// <see cref="IAsyncResponsePayload.ShouldResumeOnRecovery"/> returns <c>false</c> (or that
 48    /// cannot be classified) — arrives with no live subscriber. Typically marks the owning flow as
 49    /// failed (retriable).
 50    /// </summary>
 51    public ReflectionCallDto? FailureCallback { get; set; }
 52
 53    /// <summary>The correlation id this state belongs to; passed back into callbacks.</summary>
 54    public string? CorrelationId { get; set; }
 55
 56    /// <summary>
 57    /// Full name of the payload type the waiter subscribed for. The lost-subscriber fallback
 58    /// uses it to materialize untyped payloads (responses arriving through a broker ingress are
 59    /// raw JSON) so the payload can be asked whether to resume before a callback is chosen.
 60    /// </summary>
 61    public string? PayloadTypeFullName { get; set; }
 62
 63    /// <summary>
 64    /// UTC timestamp of the waiter registration. Used by the watchdog to detect stale recovery
 65    /// state (old entries with no live subscriber and no response in sight).
 66    /// </summary>
 67    public DateTime? RegisteredAtUtc { get; set; }
 68
 69    /// <summary>
 70    /// Serialized application ambient context captured at waiter registration (see
 71    /// <see cref="IAsyncResponseContextPropagator"/>), restored before a lost-subscriber recovery
 72    /// callback runs — which may be in a different deployment. <c>null</c> when no context
 73    /// propagators are registered.
 74    /// </summary>
 75    public Dictionary<string, string>? Context { get; set; }
 76}
 77
 78/// <summary>
 79/// Wire-schema version stamp for <see cref="RecoveryState"/>. New entries are stamped with
 80/// <see cref="Current"/>. The loader rejects (returns <c>null</c> rather than handing on a
 81/// half-interpreted entry) any persisted entry whose version is not explicitly supported. An
 82/// unrecognized writer must never silently misroute a recovery path. The JSON property is required.
 83/// <para>
 84/// Bump <see cref="Current"/> on breaking changes; the only valid new-version policy is "reject".
 85/// </para>
 86/// </summary>
 87public static class RecoveryStateSchema
 88{
 89    /// <summary>The current wire schema version written by this build.</summary>
 90    public const int Current = 1;
 91
 92    /// <summary>
 93    /// Returns <c>true</c> when an entry with <paramref name="entryVersion"/> is safe to read on
 94    /// this build. Historical versions must be listed explicitly when a tested migration path
 95    /// exists; arbitrary lower numbers are not assumed compatible.
 96    /// </summary>
 97    public static bool IsReadable(int entryVersion)
 98        => entryVersion == Current;
 99}

Methods/Properties

.ctor()