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

Information
Class: AsyncResponse.Channels.SqlServer.SqlServerAsyncResponseChannel
Assembly: AsyncResponse.Channels.SqlServer
File(s): /_/src/Channels/AsyncResponse.Channels.SqlServer/SqlServerAsyncResponseChannel.cs
Line coverage
100%
Covered lines: 17
Uncovered lines: 0
Coverable lines: 17
Total lines: 64
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ChannelName(...)100%11100%
CurrentPollInterval()100%22100%
CreateWaiter(...)100%11100%

File(s)

/_/src/Channels/AsyncResponse.Channels.SqlServer/SqlServerAsyncResponseChannel.cs

#LineLine coverage
 1// Binds the shared database-channel machinery (src/Channels/Shared/DbChannelShared.cs, compiled
 2// into this project) to this provider's concrete seam types. See the note atop the shared file.
 3global using DbChannelStore = AsyncResponse.Channels.SqlServer.SqlServerChannelSql;
 4global using DbChannelMessage = AsyncResponse.Channels.SqlServer.SqlServerChannelMessage;
 5global using DbChannelOptions = AsyncResponse.Channels.SqlServer.SqlServerAsyncResponseChannelOptions;
 6
 7using Microsoft.Extensions.DependencyInjection;
 8using Microsoft.Extensions.Logging;
 9using Microsoft.Extensions.Options;
 10
 11namespace AsyncResponse.Channels.SqlServer;
 12
 13/// <summary>
 14/// Microsoft SQL Server-backed response channel using an adaptive polling sweep for active waiter
 15/// wakeups (SQL Server has no <c>LISTEN/NOTIFY</c>) and SQL Server tables for durable recovery state.
 16/// Same-process deliveries bypass the sweep entirely; cross-process deliveries are picked up within
 17/// <see cref="SqlServerAsyncResponseChannelOptions.ActivePollInterval"/>, and the sweep backs off to
 18/// <see cref="SqlServerAsyncResponseChannelOptions.IdlePollInterval"/> while no waiters are subscribed.
 19/// </summary>
 20internal sealed class SqlServerAsyncResponseChannel : DbAsyncResponseChannelBase
 21{
 22    /// <summary>Creates a SQL Server-backed async-response channel.</summary>
 23    public SqlServerAsyncResponseChannel(
 24        IServiceScopeFactory scopeFactory,
 25        SqlServerChannelSql sql,
 26        IRecoveryStateStore recoveryStateStore,
 27        IOptions<SqlServerAsyncResponseChannelOptions> options,
 28        AsyncResponseContextPropagation propagation,
 29        ILogger<SqlServerAsyncResponseChannel> logger,
 30        TimeProvider? timeProvider = null)
 41931        : base(
 41932            scopeFactory,
 41933            sql,
 41934            recoveryStateStore,
 41935            options.Value,
 41936            propagation,
 41937            logger,
 41938            channelTypeName: nameof(SqlServerAsyncResponseChannel),
 41939            providerName: "SQL Server",
 41940            activityTag: "sqlserver",
 41941            subscriberRecordNoun: "row",
 41942            localDispatchRetryHint: "the sweep retry will pick it up",
 41943            timeProvider)
 44    {
 41945    }
 46
 47    /// <inheritdoc />
 211948    protected override string ChannelName(string correlationId) => $"{_options.SchemaName}.{_options.MessageTable}:{corr
 49
 50    /// <summary>
 51    /// The adaptive sweep cadence: tight while any waiter is subscribed (cross-process deliveries
 52    /// must land promptly), backed off while the channel is idle so an inactive application does not
 53    /// keep polling the database at delivery latency.
 54    /// </summary>
 55    protected override TimeSpan CurrentPollInterval()
 908956        => _subscriptions.IsEmpty ? _options.IdlePollInterval : _options.ActivePollInterval;
 57
 58    // No StartWakeListener override: SQL Server has no push notification, so the adaptive dispatch
 59    // sweep above IS the cross-process wake mechanism and the base keeps no listener task.
 60
 61    /// <inheritdoc />
 62    protected override IAsyncResponseWaiter<T> CreateWaiter<T>(Task<T> responseTask, Func<ValueTask> cleanupAsync)
 45663        => new SqlServerAsyncResponseWaiter<T>(responseTask, cleanupAsync);
 64}