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

Information
Class: AsyncResponse.Transports.GooglePubSub.GooglePubSubOptionsValidator
Assembly: AsyncResponse.Transports.GooglePubSub
File(s): /_/src/Transports/AsyncResponse.Transports.GooglePubSub/GooglePubSubOptionsValidator.cs
Line coverage
100%
Covered lines: 31
Uncovered lines: 0
Coverable lines: 31
Total lines: 82
Line coverage: 100%
Branch coverage
100%
Covered branches: 20
Total branches: 20
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Required(...)100%22100%
ValidateTimeouts(...)100%66100%
.cctor()100%11100%
ValidateMaxTotalAckExtension(...)100%22100%
ValidateStreamingPull(...)100%1010100%

File(s)

/_/src/Transports/AsyncResponse.Transports.GooglePubSub/GooglePubSubOptionsValidator.cs

#LineLine coverage
 1namespace AsyncResponse.Transports.GooglePubSub;
 2
 3internal static class GooglePubSubOptionsValidator
 4{
 5    /// <summary>Validates the supplied options.</summary>
 6    public static string Required(string? value, string name)
 37497        => !string.IsNullOrWhiteSpace(value)
 37498            ? value
 37499            : throw new InvalidOperationException($"{nameof(GooglePubSubAsyncResponseOptions)}.{name} must be configured
 10
 11    /// <summary>
 12    /// Common validation shared by the publisher and both subscribers: requires the
 13    /// correlation-id attribute name and bounds every timer-armed timeout — the subscriber retry
 14    /// delays feed <c>Task.Delay</c>, and <c>ShutdownTimeout</c> feeds the publisher's
 15    /// <c>ShutdownAsync</c> and the subscriber's stop timeout in every ack mode. The timeouts
 16    /// previously had NO validation at all — a negative or over-ceiling value surfaced as a raw
 17    /// timer exception inside the retry loop.
 18    /// </summary>
 19    public static void ValidateTimeouts(GooglePubSubAsyncResponseOptions options)
 20    {
 21        // Both the publish and consume paths index the message-attribute map with
 22        // CorrelationIdAttribute; a null/empty value throws from the protobuf map on the very
 23        // first message (or, behind the dispatcher's catch-all, turns into a perpetual NACK
 24        // loop), so fail fast here — the ASB sibling validates its CorrelationIdProperty the
 25        // same way.
 117926        _ = Required(options.CorrelationIdAttribute, nameof(options.CorrelationIdAttribute));
 117927        AsyncResponseChannelOptions.EnsureTimerBacked(options.SubscriberRetryBaseDelay, nameof(GooglePubSubAsyncResponse
 117528        AsyncResponseChannelOptions.EnsureTimerBacked(options.SubscriberRetryMaxDelay, nameof(GooglePubSubAsyncResponseO
 117529        if (options.SubscriberRetryBaseDelay > options.SubscriberRetryMaxDelay)
 230            throw new InvalidOperationException(
 231                $"{nameof(GooglePubSubAsyncResponseOptions)}.{nameof(options.SubscriberRetryBaseDelay)} cannot exceed {n
 117332        AsyncResponseChannelOptions.EnsureTimerBacked(options.ShutdownTimeout, nameof(GooglePubSubAsyncResponseOptions),
 116933        if (options.HostShutdownTimeout is { } hostShutdownTimeout && hostShutdownTimeout <= TimeSpan.Zero)
 234            throw new InvalidOperationException($"{nameof(GooglePubSubAsyncResponseOptions)}.{nameof(options.HostShutdow
 116735    }
 36
 37    /// <summary>
 38    /// The first lease already lasts the client's 60-second ack deadline, so a smaller total
 39    /// extension cannot make Pub/Sub redeliver sooner — it would only shrink the in-flight ceiling
 40    /// the worker transport advertises, and with it every in-process durable-flow wait.
 41    /// </summary>
 542    internal static readonly TimeSpan MinimumMaxTotalAckExtension = TimeSpan.FromMinutes(1);
 43
 44    /// <summary>The SDK's own <c>ClientCount</c> range; outside it the client build throws.</summary>
 45    internal const int MaximumClientCount = 256;
 46
 47    /// <summary>
 48    /// Bounds the ack-extension ceiling. The SDK arms one timer with it per pulled batch, so an
 49    /// over-ceiling value surfaces as a raw timer exception inside the streaming pull (and a
 50    /// perpetual subscriber restart loop) instead of failing startup.
 51    /// </summary>
 52    public static void ValidateMaxTotalAckExtension(GooglePubSubSubscriberOptions subscriberOptions, string optionPath)
 53    {
 115154        AsyncResponseChannelOptions.EnsureTimerBacked(subscriberOptions.MaxTotalAckExtension, optionPath, nameof(GoogleP
 113755        if (subscriberOptions.MaxTotalAckExtension < MinimumMaxTotalAckExtension)
 456            throw new InvalidOperationException(
 457                $"{optionPath}.{nameof(GooglePubSubSubscriberOptions.MaxTotalAckExtension)} must be at least {MinimumMax
 458                "the first lease already lasts the Pub/Sub client's 60-second ack deadline, so a smaller value cannot sp
 113359    }
 60
 61    /// <summary>
 62    /// Validates the streaming-pull settings handed to the SDK's subscriber client. The SDK checks
 63    /// them only when the client is built — inside the supervised retry loop, where a bad value
 64    /// turns into an endless rebuild-and-fail cycle rather than a startup failure.
 65    /// </summary>
 66    public static void ValidateStreamingPull(GooglePubSubSubscriberOptions subscriberOptions, string optionPath)
 67    {
 91868        ValidateMaxTotalAckExtension(subscriberOptions, optionPath);
 69
 90270        if (subscriberOptions.ClientCount is < 1 or > MaximumClientCount)
 1071            throw new InvalidOperationException(
 1072                $"{optionPath}.{nameof(GooglePubSubSubscriberOptions.ClientCount)} must be between 1 and {MaximumClientC
 73
 89274        if (subscriberOptions.MaxOutstandingMessages <= 0)
 475            throw new InvalidOperationException(
 476                $"{optionPath}.{nameof(GooglePubSubSubscriberOptions.MaxOutstandingMessages)} must be positive.");
 77
 88878        if (subscriberOptions.MaxOutstandingBytes <= 0)
 479            throw new InvalidOperationException(
 480                $"{optionPath}.{nameof(GooglePubSubSubscriberOptions.MaxOutstandingBytes)} must be positive.");
 88481    }
 82}