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

Information
Class: AsyncResponse.RecoveryStateSchema
Assembly: AsyncResponse.Abstractions
File(s): /_/src/AsyncResponse.Abstractions/RecoveryState.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 101
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
IsReadable(...)100%11100%

File(s)

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

Methods/Properties

IsReadable(System.Int32)