diff --git a/src/Particular.LicensingComponent/MonitoringThroughput/MonitoringThroughputHostedService.cs b/src/Particular.LicensingComponent/MonitoringThroughput/MonitoringThroughputHostedService.cs index 2081075b87..fc5e643bd2 100644 --- a/src/Particular.LicensingComponent/MonitoringThroughput/MonitoringThroughputHostedService.cs +++ b/src/Particular.LicensingComponent/MonitoringThroughput/MonitoringThroughputHostedService.cs @@ -26,7 +26,7 @@ public async Task StartAsync(CancellationToken cancellationToken) { logger.LogInformation("Starting {ServiceName}", nameof(MonitoringThroughputHostedService)); - transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(ServiceControlSettings.ServiceControlThroughputDataQueue, transportSettings, Handle, (_, __) => Task.FromResult(ErrorHandleResult.Handled), (_, __) => Task.CompletedTask); + transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(ServiceControlSettings.ServiceControlThroughputDataQueue, transportSettings, Handle, (_, __) => Task.FromResult(ErrorHandleResult.Handled), (_, __, ___) => Task.CompletedTask, cancellationToken: cancellationToken); await transportInfrastructure.Receivers[ServiceControlSettings.ServiceControlThroughputDataQueue].StartReceive(cancellationToken); } diff --git a/src/ServiceControl.Audit.UnitTests/.editorconfig b/src/ServiceControl.Audit.UnitTests/.editorconfig index b0c4497648..bbcb303765 100644 --- a/src/ServiceControl.Audit.UnitTests/.editorconfig +++ b/src/ServiceControl.Audit.UnitTests/.editorconfig @@ -7,5 +7,4 @@ dotnet_diagnostic.CA2007.severity = none # They are scheduled work, not accepted exceptions: remove a line once this project has no # violations of that rule left, and never add a rule back to this list. dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0013.severity = none dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Audit.UnitTests/Infrastructure/When_instance_is_setup.cs b/src/ServiceControl.Audit.UnitTests/Infrastructure/When_instance_is_setup.cs index f01c4595ea..4c2cc1d874 100644 --- a/src/ServiceControl.Audit.UnitTests/Infrastructure/When_instance_is_setup.cs +++ b/src/ServiceControl.Audit.UnitTests/Infrastructure/When_instance_is_setup.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Reflection; using System.Runtime.Loader; + using System.Threading; using System.Threading.Tasks; using Audit.Infrastructure.Hosting; using Audit.Infrastructure.Hosting.Commands; @@ -73,7 +74,7 @@ public void CustomizeMonitoringEndpoint(EndpointConfiguration endpointConfigurat public void AddTransportForMonitoring(IServiceCollection services, TransportSettings transportSettings) => throw new NotImplementedException(); - public Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues) + public Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues, CancellationToken cancellationToken = default) { QueuesCreated = [ @@ -85,8 +86,9 @@ public Task ProvisionQueues(TransportSettings transportSettings, IEnumerable CreateTransportInfrastructure(string name, TransportSettings transportSettings, - OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, - TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly) => + OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, + TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly, + CancellationToken cancellationToken = default) => throw new NotImplementedException(); public string ToTransportQualifiedQueueName(string queueName) => queueName; } diff --git a/src/ServiceControl.Audit/.editorconfig b/src/ServiceControl.Audit/.editorconfig index 46637f1f91..ff993b49bb 100644 --- a/src/ServiceControl.Audit/.editorconfig +++ b/src/ServiceControl.Audit/.editorconfig @@ -2,10 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Blocked on the transport abstraction. TransportCustomization.CreateTransportInfrastructure takes -# Func for onCriticalError, so the critical-error path here cannot carry a -# token until that signature gains one in the transports phase. -[{Auditing/AuditIngestion.cs,Auditing/AuditIngestionFaultPolicy.cs,Auditing/ImportFailureCircuitBreaker.cs}] -dotnet_diagnostic.PS0013.severity = none -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestion.cs b/src/ServiceControl.Audit/Auditing/AuditIngestion.cs index 0b14b2724d..69e312965c 100644 --- a/src/ServiceControl.Audit/Auditing/AuditIngestion.cs +++ b/src/ServiceControl.Audit/Auditing/AuditIngestion.cs @@ -68,10 +68,10 @@ ILogger logger ); } - Task OnCriticalError(string failure, Exception exception) + Task OnCriticalError(string failure, Exception exception, CancellationToken cancellationToken) { logger.LogCritical(exception, "OnCriticalError. '{Failure}'", failure); - return watchdog.OnFailure(failure); + return watchdog.OnFailure(failure, cancellationToken); } async Task EnsureStarted(CancellationToken cancellationToken) @@ -137,7 +137,8 @@ async Task SetUpAndStartInfrastructure(CancellationToken cancellationToken) OnMessage, errorHandlingPolicy.OnError, OnCriticalError, - TransportTransactionMode.ReceiveOnly + TransportTransactionMode.ReceiveOnly, + cancellationToken ); messageReceiver = transportInfrastructure.Receivers[inputEndpoint]; diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs index fab0a13e1b..c87ca5d5dc 100644 --- a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs +++ b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs @@ -20,7 +20,7 @@ class AuditIngestionFaultPolicy public AuditIngestionFaultPolicy( IFailedAuditStorage failedAuditStorage, LoggingSettings settings, - Func onCriticalError, + Func onCriticalError, IngestionMetrics metrics, ILogger logger) { diff --git a/src/ServiceControl.Audit/Auditing/ImportFailureCircuitBreaker.cs b/src/ServiceControl.Audit/Auditing/ImportFailureCircuitBreaker.cs index 658e7fc859..df2b007e9f 100644 --- a/src/ServiceControl.Audit/Auditing/ImportFailureCircuitBreaker.cs +++ b/src/ServiceControl.Audit/Auditing/ImportFailureCircuitBreaker.cs @@ -7,7 +7,7 @@ class ImportFailureCircuitBreaker : IDisposable { - public ImportFailureCircuitBreaker(Func onCriticalError) + public ImportFailureCircuitBreaker(Func onCriticalError) { this.onCriticalError = onCriticalError; timer = new Timer(_ => FlushHistory(), null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(20)); @@ -28,11 +28,13 @@ public void Increment(Exception lastException) var result = Interlocked.Increment(ref failureCount); if (result > 50) { - _ = Task.Run(() => onCriticalError("Failed to import too many times", lastException)); + // Not cancellable: the notification exists to trigger shutdown, so the token + // that shutdown cancels must not be able to suppress it. + _ = Task.Run(() => onCriticalError("Failed to import too many times", lastException, CancellationToken.None), CancellationToken.None); } } - Func onCriticalError; + Func onCriticalError; Timer timer; long failureCount; } diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs index 3260fa5add..9b20270d8e 100644 --- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs +++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs @@ -33,7 +33,7 @@ public override async Task Execute(HostArguments args, Settings settings, Cancel transportSettings.RunCustomChecks = false; var transportCustomization = TransportFactory.Create(transportSettings); - await transportCustomization.ProvisionQueues(transportSettings, additionalQueues); + await transportCustomization.ProvisionQueues(transportSettings, additionalQueues, cancellationToken); } } diff --git a/src/ServiceControl.Persistence.Tests/RetryStateTests.cs b/src/ServiceControl.Persistence.Tests/RetryStateTests.cs index 5277ccf869..34b3cabb1d 100644 --- a/src/ServiceControl.Persistence.Tests/RetryStateTests.cs +++ b/src/ServiceControl.Persistence.Tests/RetryStateTests.cs @@ -500,13 +500,14 @@ public class TestTransportCustomization : ITransportCustomization public Task CreateTransportInfrastructure(string name, TransportSettings transportSettings, OnMessage onMessage = null, OnError onError = null, - Func onCriticalError = null, + Func onCriticalError = null, NServiceBus.TransportTransactionMode preferredTransactionMode = - NServiceBus.TransportTransactionMode.ReceiveOnly) => Task.FromResult(TransportInfrastructure); + NServiceBus.TransportTransactionMode.ReceiveOnly, + CancellationToken cancellationToken = default) => Task.FromResult(TransportInfrastructure); public void CustomizeAuditEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TransportSettings transportSettings) => throw new NotImplementedException(); public void CustomizeMonitoringEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TransportSettings transportSettings) => throw new NotImplementedException(); public void CustomizePrimaryEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TransportSettings transportSettings) => throw new NotImplementedException(); - public Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues) => throw new NotImplementedException(); + public Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); public string ToTransportQualifiedQueueName(string queueName) => queueName; } diff --git a/src/ServiceControl.Transports.ASBS.Tests/.editorconfig b/src/ServiceControl.Transports.ASBS.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.ASBS.Tests/.editorconfig +++ b/src/ServiceControl.Transports.ASBS.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.ASBS.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.ASBS.Tests/TransportTestsConfiguration.cs index e5fd0f1e68..a4663a3899 100644 --- a/src/ServiceControl.Transports.ASBS.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.ASBS.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.ASBS; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new ASBSTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_ASBS_ConnectionString"; } diff --git a/src/ServiceControl.Transports.ASBS/.editorconfig b/src/ServiceControl.Transports.ASBS/.editorconfig index 430f2565bd..ff993b49bb 100644 --- a/src/ServiceControl.Transports.ASBS/.editorconfig +++ b/src/ServiceControl.Transports.ASBS/.editorconfig @@ -2,10 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0004.severity = none -dotnet_diagnostic.PS0017.severity = none diff --git a/src/ServiceControl.Transports.ASBS/ASBSTransportCustomization.cs b/src/ServiceControl.Transports.ASBS/ASBSTransportCustomization.cs index 1498b5490c..778dec09d5 100644 --- a/src/ServiceControl.Transports.ASBS/ASBSTransportCustomization.cs +++ b/src/ServiceControl.Transports.ASBS/ASBSTransportCustomization.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json; + using System.Threading; using System.Threading.Tasks; using Azure.Messaging.ServiceBus; using Azure.Messaging.ServiceBus.Administration; @@ -99,9 +100,9 @@ protected override void AddTransportForMonitoringCore(IServiceCollection service services.AddHostedService(provider => provider.GetRequiredService()); } - public override async Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues) + public override async Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues, CancellationToken cancellationToken = default) { - await base.ProvisionQueues(transportSettings, additionalQueues); + await base.ProvisionQueues(transportSettings, additionalQueues, cancellationToken); if (transportSettings.EventTypesPublished.Count == 0) { @@ -132,7 +133,7 @@ async Task CreateTopic(string publishedTopic) try { - await managementClient.CreateTopicAsync(topicToPublishTo).ConfigureAwait(false); + await managementClient.CreateTopicAsync(topicToPublishTo, cancellationToken).ConfigureAwait(false); } catch (ServiceBusException sbe) when (sbe.Reason == ServiceBusFailureReason.MessagingEntityAlreadyExists || sbe.IsTransient) { diff --git a/src/ServiceControl.Transports.ASBS/AzureQuery.cs b/src/ServiceControl.Transports.ASBS/AzureQuery.cs index 7bf37a9bc7..fa1430251a 100644 --- a/src/ServiceControl.Transports.ASBS/AzureQuery.cs +++ b/src/ServiceControl.Transports.ASBS/AzureQuery.cs @@ -201,7 +201,7 @@ public string ExtractServiceBusName() public override async IAsyncEnumerable GetThroughputPerDay(IBrokerQueue brokerQueue, DateOnly startDate, - [EnumeratorCancellation] CancellationToken cancellationToken) + [EnumeratorCancellation] CancellationToken cancellationToken = default) { logger.LogInformation($"Gathering metrics for \"{brokerQueue.QueueName}\" queue"); @@ -249,7 +249,7 @@ public override async IAsyncEnumerable GetThroughputPerDay(IBro } async Task> GetMetrics(string queueName, DateOnly startTime, DateOnly endTime, - CancellationToken cancellationToken = default) + CancellationToken cancellationToken) { var options = new ArmResourceGetMonitorMetricsOptions() { @@ -272,7 +272,7 @@ async Task> GetMetrics(string queueName, DateO } public override async IAsyncEnumerable GetQueueNames( - [EnumeratorCancellation] CancellationToken cancellationToken) + [EnumeratorCancellation] CancellationToken cancellationToken = default) { var validNamespaces = await GetValidNamespaceNames(cancellationToken); @@ -310,7 +310,7 @@ public override async IAsyncEnumerable GetQueueNames( { ArmEnvironment.AzureChina, "servicebus.chinacloudapi.cn" }, }; - async Task> GetValidNamespaceNames(CancellationToken cancellationToken = default) + async Task> GetValidNamespaceNames(CancellationToken cancellationToken) { var validNamespaces = new HashSet(StringComparer.OrdinalIgnoreCase) { serviceBusName }; @@ -347,7 +347,7 @@ async Task> GetValidNamespaceNames(CancellationToken cancellatio ]; protected override async Task<(bool Success, List Errors)> TestConnectionCore( - CancellationToken cancellationToken) + CancellationToken cancellationToken = default) { await foreach (IBrokerQueue brokerQueue in GetQueueNames(cancellationToken)) { diff --git a/src/ServiceControl.Transports.ASBS/QueueLengthProvider.cs b/src/ServiceControl.Transports.ASBS/QueueLengthProvider.cs index 8978c03fed..2538772c49 100644 --- a/src/ServiceControl.Transports.ASBS/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.ASBS/QueueLengthProvider.cs @@ -27,24 +27,24 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack (id, old) => queueToTrack.EndpointName ); - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { logger.LogDebug("Waiting for next interval"); - await Task.Delay(queryDelayInterval, stoppingToken); + await Task.Delay(queryDelayInterval, cancellationToken); logger.LogDebug("Querying management client"); - var queueRuntimeInfos = await GetQueueList(stoppingToken); + var queueRuntimeInfos = await GetQueueList(cancellationToken); logger.LogDebug("Retrieved details of {QueueCount} queues", queueRuntimeInfos.Count); UpdateAllQueueLengths(queueRuntimeInfos); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } diff --git a/src/ServiceControl.Transports.ASQ.Tests/.editorconfig b/src/ServiceControl.Transports.ASQ.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.ASQ.Tests/.editorconfig +++ b/src/ServiceControl.Transports.ASQ.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.ASQ.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.ASQ.Tests/TransportTestsConfiguration.cs index 3a566e7d00..1532375f86 100644 --- a/src/ServiceControl.Transports.ASQ.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.ASQ.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.ASQ; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new ASQTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_ASQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.ASQ/.editorconfig b/src/ServiceControl.Transports.ASQ/.editorconfig index 13cac70b79..ff993b49bb 100644 --- a/src/ServiceControl.Transports.ASQ/.editorconfig +++ b/src/ServiceControl.Transports.ASQ/.editorconfig @@ -2,9 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0017.severity = none diff --git a/src/ServiceControl.Transports.ASQ/QueueLengthProvider.cs b/src/ServiceControl.Transports.ASQ/QueueLengthProvider.cs index 01b29e98fd..4a2b245798 100644 --- a/src/ServiceControl.Transports.ASQ/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.ASQ/QueueLengthProvider.cs @@ -33,19 +33,19 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack queueLengths.AddOrUpdate(queueToTrack, _ => emptyQueueLength, (_, existingQueueLength) => existingQueueLength); } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { - await FetchQueueSizes(stoppingToken); + await FetchQueueSizes(cancellationToken); UpdateQueueLengthStore(); - await Task.Delay(QueryDelayInterval, stoppingToken); + await Task.Delay(QueryDelayInterval, cancellationToken); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } diff --git a/src/ServiceControl.Transports.IBMMQ.Tests/.editorconfig b/src/ServiceControl.Transports.IBMMQ.Tests/.editorconfig deleted file mode 100644 index 2815635efb..0000000000 --- a/src/ServiceControl.Transports.IBMMQ.Tests/.editorconfig +++ /dev/null @@ -1,6 +0,0 @@ -[*.cs] - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.IBMMQ.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.IBMMQ.Tests/TransportTestsConfiguration.cs index da512c3ce5..7fd24e7551 100644 --- a/src/ServiceControl.Transports.IBMMQ.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.IBMMQ.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests; using System; +using System.Threading; using System.Threading.Tasks; using Transports; using Transports.IBMMQ; @@ -21,7 +22,7 @@ class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new TestIBMMQTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey) @@ -35,7 +36,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_IBMMQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.IBMMQ/.editorconfig b/src/ServiceControl.Transports.IBMMQ/.editorconfig deleted file mode 100644 index 1942f21999..0000000000 --- a/src/ServiceControl.Transports.IBMMQ/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -[*.cs] - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0017.severity = none diff --git a/src/ServiceControl.Transports.IBMMQ/QueueLengthProvider.cs b/src/ServiceControl.Transports.IBMMQ/QueueLengthProvider.cs index 7dcf53bcc2..abea3c1ec5 100644 --- a/src/ServiceControl.Transports.IBMMQ/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.IBMMQ/QueueLengthProvider.cs @@ -29,9 +29,9 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack return queueToTrack.InputQueue; }); - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { @@ -39,9 +39,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) UpdateQueueLengthStore(); - await Task.Delay(QueryDelayInterval, stoppingToken).ConfigureAwait(false); + await Task.Delay(QueryDelayInterval, cancellationToken).ConfigureAwait(false); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } @@ -49,7 +49,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { logger.LogError(e, "Queue length query loop failure"); CloseConnection(); - await Task.Delay(ReconnectDelayInterval, stoppingToken).ConfigureAwait(false); + await Task.Delay(ReconnectDelayInterval, cancellationToken).ConfigureAwait(false); } } diff --git a/src/ServiceControl.Transports.Learning/.editorconfig b/src/ServiceControl.Transports.Learning/.editorconfig index 13cac70b79..ff993b49bb 100644 --- a/src/ServiceControl.Transports.Learning/.editorconfig +++ b/src/ServiceControl.Transports.Learning/.editorconfig @@ -2,9 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0017.severity = none diff --git a/src/ServiceControl.Transports.Learning/QueueLengthProvider.cs b/src/ServiceControl.Transports.Learning/QueueLengthProvider.cs index 93bc2fcc41..345b402698 100644 --- a/src/ServiceControl.Transports.Learning/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.Learning/QueueLengthProvider.cs @@ -22,18 +22,18 @@ public QueueLengthProvider(TransportSettings settings, Action endpointsHash.AddOrUpdate(queueToTrack, queueToTrack, (_, __) => queueToTrack); - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { var queueLengths = GetQueueLengths(); UpdateStore(queueLengths); - await Task.Delay(QueryDelayInterval, stoppingToken); + await Task.Delay(QueryDelayInterval, cancellationToken); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // It's OK. We're shutting down } diff --git a/src/ServiceControl.Transports.Msmq.Tests/.editorconfig b/src/ServiceControl.Transports.Msmq.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.Msmq.Tests/.editorconfig +++ b/src/ServiceControl.Transports.Msmq.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.Msmq.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.Msmq.Tests/TransportTestsConfiguration.cs index 15c4235f58..d2277d2805 100644 --- a/src/ServiceControl.Transports.Msmq.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.Msmq.Tests/TransportTestsConfiguration.cs @@ -1,5 +1,6 @@ namespace ServiceControl.Transport.Tests { + using System.Threading; using System.Threading.Tasks; using ServiceControl.Transports; using ServiceControl.Transports.Msmq; @@ -10,7 +11,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new MsmqTransportCustomization(); ConnectionString = null; @@ -18,6 +19,6 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; } } \ No newline at end of file diff --git a/src/ServiceControl.Transports.Msmq/.editorconfig b/src/ServiceControl.Transports.Msmq/.editorconfig index eae5d84087..ff993b49bb 100644 --- a/src/ServiceControl.Transports.Msmq/.editorconfig +++ b/src/ServiceControl.Transports.Msmq/.editorconfig @@ -2,8 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none diff --git a/src/ServiceControl.Transports.Msmq/NoOpQueueLengthProvider.cs b/src/ServiceControl.Transports.Msmq/NoOpQueueLengthProvider.cs index b1f9499da7..d9a6d02c95 100644 --- a/src/ServiceControl.Transports.Msmq/NoOpQueueLengthProvider.cs +++ b/src/ServiceControl.Transports.Msmq/NoOpQueueLengthProvider.cs @@ -10,8 +10,8 @@ public void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack) //This is a no op for MSMQ since the endpoints report their queue length to SC using custom messages } - public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public Task StartAsync(CancellationToken cancellationToken = default) => Task.CompletedTask; - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public Task StopAsync(CancellationToken cancellationToken = default) => Task.CompletedTask; } } \ No newline at end of file diff --git a/src/ServiceControl.Transports.PostgreSql.Tests/.editorconfig b/src/ServiceControl.Transports.PostgreSql.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.PostgreSql.Tests/.editorconfig +++ b/src/ServiceControl.Transports.PostgreSql.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.PostgreSql.Tests/PostgreSqlQueryTests.cs b/src/ServiceControl.Transports.PostgreSql.Tests/PostgreSqlQueryTests.cs index 4de9c5c636..eede2d1b0d 100644 --- a/src/ServiceControl.Transports.PostgreSql.Tests/PostgreSqlQueryTests.cs +++ b/src/ServiceControl.Transports.PostgreSql.Tests/PostgreSqlQueryTests.cs @@ -155,7 +155,7 @@ public async Task NoNegativeThroughputWhenQueueTableIsDeletedBetweenSnapshots() // Drop the table mid-way while GetThroughputPerDay is waiting for the next hour if (advanceCount == 3) { - await DropQueueTable(brokerQueueTable.QueueAddress.QualifiedTableName); + await DropQueueTable(brokerQueueTable.QueueAddress.QualifiedTableName, token); } provider.Advance(TimeSpan.FromHours(1)); @@ -179,12 +179,12 @@ public async Task NoNegativeThroughputWhenQueueTableIsDeletedBetweenSnapshots() Assert.That(throughputValues, Has.All.Matches(qt => qt.TotalThroughput >= 0)); } - async Task DropQueueTable(string qualifiedTableName) + async Task DropQueueTable(string qualifiedTableName, CancellationToken cancellationToken) { await using var conn = new NpgsqlConnection(configuration.ConnectionString); - await conn.OpenAsync(); + await conn.OpenAsync(cancellationToken); await using var cmd = conn.CreateCommand(); cmd.CommandText = $"DROP TABLE IF EXISTS {qualifiedTableName} CASCADE;"; - await cmd.ExecuteNonQueryAsync(); + await cmd.ExecuteNonQueryAsync(cancellationToken); } } \ No newline at end of file diff --git a/src/ServiceControl.Transports.PostgreSql.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.PostgreSql.Tests/TransportTestsConfiguration.cs index 819248c612..12e0d3b091 100644 --- a/src/ServiceControl.Transports.PostgreSql.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.PostgreSql.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using ServiceControl.Transports.PostgreSql; using Transports; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new PostgreSqlTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; const string ConnectionStringKey = "ServiceControl_TransportTests_PostgreSQL_ConnectionString"; } diff --git a/src/ServiceControl.Transports.PostgreSql/.editorconfig b/src/ServiceControl.Transports.PostgreSql/.editorconfig index efbfc38b1f..ff993b49bb 100644 --- a/src/ServiceControl.Transports.PostgreSql/.editorconfig +++ b/src/ServiceControl.Transports.PostgreSql/.editorconfig @@ -2,11 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0004.severity = none -dotnet_diagnostic.PS0017.severity = none -dotnet_diagnostic.PS0019.severity = none diff --git a/src/ServiceControl.Transports.PostgreSql/DatabaseDetails.cs b/src/ServiceControl.Transports.PostgreSql/DatabaseDetails.cs index 93474ae67c..e90ed6959b 100644 --- a/src/ServiceControl.Transports.PostgreSql/DatabaseDetails.cs +++ b/src/ServiceControl.Transports.PostgreSql/DatabaseDetails.cs @@ -29,7 +29,7 @@ public DatabaseDetails(string connectionString) } } - public async Task TestConnection(CancellationToken cancellationToken) + public async Task TestConnection(CancellationToken cancellationToken = default) { try { @@ -117,7 +117,7 @@ public async Task GetSnapshot(BrokerQueueTable brokerQ return table; } - async Task OpenConnectionAsync(CancellationToken cancellationToken = default) + async Task OpenConnectionAsync(CancellationToken cancellationToken) { var conn = new NpgsqlConnection(connectionString); await conn.OpenAsync(cancellationToken); diff --git a/src/ServiceControl.Transports.PostgreSql/PostgreSqlQuery.cs b/src/ServiceControl.Transports.PostgreSql/PostgreSqlQuery.cs index 7d50e07906..cc1e55da63 100644 --- a/src/ServiceControl.Transports.PostgreSql/PostgreSqlQuery.cs +++ b/src/ServiceControl.Transports.PostgreSql/PostgreSqlQuery.cs @@ -89,7 +89,7 @@ public override async IAsyncEnumerable GetQueueNames( ]; protected override async Task<(bool Success, List Errors)> TestConnectionCore( - CancellationToken cancellationToken) + CancellationToken cancellationToken = default) { List errors = []; @@ -99,6 +99,10 @@ public override async IAsyncEnumerable GetQueueNames( { await db.TestConnection(cancellationToken); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception ex) { logger.LogError(ex, "Test connection failed"); diff --git a/src/ServiceControl.Transports.PostgreSql/QueueLengthProvider.cs b/src/ServiceControl.Transports.PostgreSql/QueueLengthProvider.cs index e6067e131e..a4f2f2cc74 100644 --- a/src/ServiceControl.Transports.PostgreSql/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.PostgreSql/QueueLengthProvider.cs @@ -38,19 +38,19 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack tableSizes.TryAdd(sqlTable, 0); } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { - await Task.Delay(QueryDelayInterval, stoppingToken); + await Task.Delay(QueryDelayInterval, cancellationToken); - await QueryTableSizes(stoppingToken); + await QueryTableSizes(cancellationToken); UpdateQueueLengthStore(); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } diff --git a/src/ServiceControl.Transports.RabbitMQ/.editorconfig b/src/ServiceControl.Transports.RabbitMQ/.editorconfig index 9927cfeb58..ff993b49bb 100644 --- a/src/ServiceControl.Transports.RabbitMQ/.editorconfig +++ b/src/ServiceControl.Transports.RabbitMQ/.editorconfig @@ -2,10 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0017.severity = none -dotnet_diagnostic.PS0019.severity = none diff --git a/src/ServiceControl.Transports.RabbitMQ/QueueLengthProvider.cs b/src/ServiceControl.Transports.RabbitMQ/QueueLengthProvider.cs index 31d2c128e6..ef74db62e3 100644 --- a/src/ServiceControl.Transports.RabbitMQ/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.RabbitMQ/QueueLengthProvider.cs @@ -34,19 +34,19 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack return queueToTrack.InputQueue; }); - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { - await FetchQueueLengths(stoppingToken); + await FetchQueueLengths(cancellationToken); UpdateQueueLengths(); - await Task.Delay(QueryDelayInterval, stoppingToken); + await Task.Delay(QueryDelayInterval, cancellationToken); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } @@ -91,6 +91,10 @@ async Task FetchQueueLengths(CancellationToken cancellationToken) var size = queue.MessageCount; sizes.AddOrUpdate(queueName, _ => size, (_, _) => size); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception e) { logger.LogWarning(e, "Error querying queue length for {QueueName}", queueName); diff --git a/src/ServiceControl.Transports.RabbitMQ/RabbitMQQuery.cs b/src/ServiceControl.Transports.RabbitMQ/RabbitMQQuery.cs index 8367d46bcb..e2ef02c553 100644 --- a/src/ServiceControl.Transports.RabbitMQ/RabbitMQQuery.cs +++ b/src/ServiceControl.Transports.RabbitMQ/RabbitMQQuery.cs @@ -66,7 +66,7 @@ public override async IAsyncEnumerable GetThroughputPerDay(IBro } } - public override async IAsyncEnumerable GetQueueNames([EnumeratorCancellation] CancellationToken cancellationToken) + public override async IAsyncEnumerable GetQueueNames([EnumeratorCancellation] CancellationToken cancellationToken = default) { var page = 1; bool morePages; @@ -149,7 +149,7 @@ async Task AddEndpointIndicators(RabbitMQBrokerQueue brokerQueue, CancellationTo public override KeyDescriptionPair[] Settings => []; - protected override async Task<(bool Success, List Errors)> TestConnectionCore(CancellationToken cancellationToken) + protected override async Task<(bool Success, List Errors)> TestConnectionCore(CancellationToken cancellationToken = default) { try { diff --git a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/.editorconfig b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/.editorconfig +++ b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/TransportTestsConfiguration.cs index 6b40b25ca5..7bae43f7f0 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.RabbitMQClassicConventionalRouting.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.RabbitMQ; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new RabbitMQClassicConventionalRoutingTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_RabbitMQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/.editorconfig b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/.editorconfig +++ b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/TransportTestsConfiguration.cs index ca493aea27..d2449ac20a 100644 --- a/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.RabbitMQClassicDirectRouting.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using ServiceControl.Transports.RabbitMQ; using Transports; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new RabbitMQClassicDirectRoutingTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_RabbitMQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/.editorconfig b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/.editorconfig +++ b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/TransportTestsConfiguration.cs index 6601843755..3e0f665d4b 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.RabbitMQQuorumConventionalRouting.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using ServiceControl.Transports.RabbitMQ; using Transports; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new RabbitMQQuorumConventionalRoutingTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_RabbitMQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/.editorconfig b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/.editorconfig +++ b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/TransportTestsConfiguration.cs index 7bfc45c6e3..0e8c83478e 100644 --- a/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.RabbitMQQuorumDirectRouting.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.RabbitMQ; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new RabbitMQQuorumDirectRoutingTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_RabbitMQ_ConnectionString"; } diff --git a/src/ServiceControl.Transports.SQS.Tests/.editorconfig b/src/ServiceControl.Transports.SQS.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.SQS.Tests/.editorconfig +++ b/src/ServiceControl.Transports.SQS.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.SQS.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.SQS.Tests/TransportTestsConfiguration.cs index c64f5d1bca..f0dc7d3b07 100644 --- a/src/ServiceControl.Transports.SQS.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.SQS.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.SQS; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new SQSTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_SQS_ConnectionString"; } diff --git a/src/ServiceControl.Transports.SQS/.editorconfig b/src/ServiceControl.Transports.SQS/.editorconfig index 13cac70b79..ff993b49bb 100644 --- a/src/ServiceControl.Transports.SQS/.editorconfig +++ b/src/ServiceControl.Transports.SQS/.editorconfig @@ -2,9 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0017.severity = none diff --git a/src/ServiceControl.Transports.SQS/AmazonSQSQuery.cs b/src/ServiceControl.Transports.SQS/AmazonSQSQuery.cs index 5f233d8e92..dfc4d7b33f 100644 --- a/src/ServiceControl.Transports.SQS/AmazonSQSQuery.cs +++ b/src/ServiceControl.Transports.SQS/AmazonSQSQuery.cs @@ -196,7 +196,7 @@ class AwsHttpClientFactory : HttpClientFactory public override async IAsyncEnumerable GetThroughputPerDay(IBrokerQueue brokerQueue, DateOnly startDate, - [EnumeratorCancellation] CancellationToken cancellationToken) + [EnumeratorCancellation] CancellationToken cancellationToken = default) { var utcNow = timeProvider.GetUtcNow(); var today = DateOnly.FromDateTime(utcNow.DateTime); @@ -306,7 +306,7 @@ public override async IAsyncEnumerable GetQueueNames( ]; protected override async Task<(bool Success, List Errors)> TestConnectionCore( - CancellationToken cancellationToken) + CancellationToken cancellationToken = default) { await foreach (IBrokerQueue brokerQueue in GetQueueNames(cancellationToken)) { diff --git a/src/ServiceControl.Transports.SQS/QueueLengthProvider.cs b/src/ServiceControl.Transports.SQS/QueueLengthProvider.cs index 7c8d01fc3f..0cc527497c 100644 --- a/src/ServiceControl.Transports.SQS/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.SQS/QueueLengthProvider.cs @@ -52,22 +52,22 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack sizes.TryAdd(queue, 0); } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { using var client = clientFactory(); var cache = new QueueAttributesRequestCache(client); - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { try { - await FetchQueueSizes(cache, client, stoppingToken); + await FetchQueueSizes(cache, client, cancellationToken); UpdateQueueLengthStore(); - await Task.Delay(QueryDelayInterval, stoppingToken); + await Task.Delay(QueryDelayInterval, cancellationToken); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // no-op } diff --git a/src/ServiceControl.Transports.SqlServer.Tests/.editorconfig b/src/ServiceControl.Transports.SqlServer.Tests/.editorconfig index 0a6ae3dffe..5f68a610b3 100644 --- a/src/ServiceControl.Transports.SqlServer.Tests/.editorconfig +++ b/src/ServiceControl.Transports.SqlServer.Tests/.editorconfig @@ -2,8 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.SqlServer.Tests/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.SqlServer.Tests/TransportTestsConfiguration.cs index 9cf82c6dde..f1d124cc53 100644 --- a/src/ServiceControl.Transports.SqlServer.Tests/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.SqlServer.Tests/TransportTestsConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Transport.Tests { using System; + using System.Threading; using System.Threading.Tasks; using Transports; using Transports.SqlServer; @@ -11,7 +12,7 @@ partial class TransportTestsConfiguration public ITransportCustomization TransportCustomization { get; private set; } - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { TransportCustomization = new SqlServerTransportCustomization(); ConnectionString = Environment.GetEnvironmentVariable(ConnectionStringKey); @@ -24,7 +25,7 @@ public Task Configure() return Task.CompletedTask; } - public Task Cleanup() => Task.CompletedTask; + public Task Cleanup(CancellationToken cancellationToken = default) => Task.CompletedTask; static string ConnectionStringKey = "ServiceControl_TransportTests_SQL_ConnectionString"; } diff --git a/src/ServiceControl.Transports.SqlServer/.editorconfig b/src/ServiceControl.Transports.SqlServer/.editorconfig index efbfc38b1f..ff993b49bb 100644 --- a/src/ServiceControl.Transports.SqlServer/.editorconfig +++ b/src/ServiceControl.Transports.SqlServer/.editorconfig @@ -2,11 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0004.severity = none -dotnet_diagnostic.PS0017.severity = none -dotnet_diagnostic.PS0019.severity = none diff --git a/src/ServiceControl.Transports.SqlServer/DatabaseDetails.cs b/src/ServiceControl.Transports.SqlServer/DatabaseDetails.cs index 54bb7151af..0ff57251e7 100644 --- a/src/ServiceControl.Transports.SqlServer/DatabaseDetails.cs +++ b/src/ServiceControl.Transports.SqlServer/DatabaseDetails.cs @@ -30,7 +30,7 @@ public DatabaseDetails(string connectionString) } } - public async Task TestConnection(CancellationToken cancellationToken) + public async Task TestConnection(CancellationToken cancellationToken = default) { try { @@ -131,7 +131,7 @@ public async Task GetSnapshot(BrokerQueueTable brokerQ return table; } - async Task OpenConnectionAsync(CancellationToken cancellationToken = default) + async Task OpenConnectionAsync(CancellationToken cancellationToken) { var conn = new SqlConnection(connectionString); await conn.OpenAsync(cancellationToken); diff --git a/src/ServiceControl.Transports.SqlServer/QueueLengthProvider.cs b/src/ServiceControl.Transports.SqlServer/QueueLengthProvider.cs index b2cdfd653f..f108fd34d4 100644 --- a/src/ServiceControl.Transports.SqlServer/QueueLengthProvider.cs +++ b/src/ServiceControl.Transports.SqlServer/QueueLengthProvider.cs @@ -53,9 +53,9 @@ public override void TrackEndpointInputQueue(EndpointToQueueMapping queueToTrack tableSizes.TryAdd(sqlTable, 0); } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken cancellationToken = default) { - while (!stoppingToken.IsCancellationRequested) + while (!cancellationToken.IsCancellationRequested) { // Time the whole iteration so the pacing delay below can subtract the work already done this // cycle. The effective cadence is then max(currentDelay, iterationDuration) — the query @@ -66,7 +66,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) try { - await QueryTableSizes(stoppingToken); + await QueryTableSizes(cancellationToken); UpdateQueueLengthStore(); @@ -79,7 +79,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) var maxObservedLength = tableSizes.IsEmpty ? 0 : tableSizes.Values.Max(); currentDelay = NextDelay(currentDelay, baseDelay, maxDelay, maxObservedLength); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { break; } @@ -97,9 +97,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { - await Task.Delay(remaining, stoppingToken); + await Task.Delay(remaining, cancellationToken); } - catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { break; } diff --git a/src/ServiceControl.Transports.SqlServer/SqlServerQuery.cs b/src/ServiceControl.Transports.SqlServer/SqlServerQuery.cs index e014475abf..c948ee36bb 100644 --- a/src/ServiceControl.Transports.SqlServer/SqlServerQuery.cs +++ b/src/ServiceControl.Transports.SqlServer/SqlServerQuery.cs @@ -66,6 +66,10 @@ public override async IAsyncEnumerable GetThroughputPerDay(IBro { startData = await queueTableName.DatabaseDetails.GetSnapshot(queueTableName, cancellationToken); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception e) { logger.LogError(e, "Failed to query throughput starting snapshot for {QueueName}", queueTableName.QueueName); @@ -82,6 +86,10 @@ public override async IAsyncEnumerable GetThroughputPerDay(IBro { endData = await queueTableName.DatabaseDetails.GetSnapshot(queueTableName, cancellationToken); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception e) { logger.LogError(e, "Failed to query throughput hour {hour} for {QueueName}", i, queueTableName.QueueName); @@ -130,7 +138,7 @@ public override async IAsyncEnumerable GetQueueNames( ]; protected override async Task<(bool Success, List Errors)> TestConnectionCore( - CancellationToken cancellationToken) + CancellationToken cancellationToken = default) { List errors = []; @@ -140,6 +148,10 @@ public override async IAsyncEnumerable GetQueueNames( { await db.TestConnection(cancellationToken); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception ex) { logger.LogError(ex, "Test connection failed"); diff --git a/src/ServiceControl.Transports.Tests/.editorconfig b/src/ServiceControl.Transports.Tests/.editorconfig index 062de7d0db..5f68a610b3 100644 --- a/src/ServiceControl.Transports.Tests/.editorconfig +++ b/src/ServiceControl.Transports.Tests/.editorconfig @@ -2,9 +2,3 @@ # Justification: Test project dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0013.severity = none -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt b/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt index 60330b755d..7963f24901 100644 --- a/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt +++ b/src/ServiceControl.Transports.Tests/ApprovalFiles/APIApprovals.ServiceControlTransport.approved.txt @@ -6,7 +6,7 @@ namespace ServiceControl.Transports protected AbstractQueueLengthProvider(ServiceControl.Transports.TransportSettings settings, System.Action store) { } protected string ConnectionString { get; } protected System.Action Store { get; } - public override System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken) { } + public override System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken = default) { } public abstract void TrackEndpointInputQueue(ServiceControl.Transports.EndpointToQueueMapping queueToTrack); } public class EndpointToQueueMapping @@ -27,11 +27,11 @@ namespace ServiceControl.Transports void AddTransportForAudit(Microsoft.Extensions.DependencyInjection.IServiceCollection services, ServiceControl.Transports.TransportSettings transportSettings); void AddTransportForMonitoring(Microsoft.Extensions.DependencyInjection.IServiceCollection services, ServiceControl.Transports.TransportSettings transportSettings); void AddTransportForPrimary(Microsoft.Extensions.DependencyInjection.IServiceCollection services, ServiceControl.Transports.TransportSettings transportSettings); - System.Threading.Tasks.Task CreateTransportInfrastructure(string name, ServiceControl.Transports.TransportSettings transportSettings, NServiceBus.Transport.OnMessage onMessage = null, NServiceBus.Transport.OnError onError = null, System.Func onCriticalError = null, NServiceBus.TransportTransactionMode preferredTransactionMode = 1); + System.Threading.Tasks.Task CreateTransportInfrastructure(string name, ServiceControl.Transports.TransportSettings transportSettings, NServiceBus.Transport.OnMessage onMessage = null, NServiceBus.Transport.OnError onError = null, System.Func onCriticalError = null, NServiceBus.TransportTransactionMode preferredTransactionMode = 1, System.Threading.CancellationToken cancellationToken = default); void CustomizeAuditEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings); void CustomizeMonitoringEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings); void CustomizePrimaryEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings); - System.Threading.Tasks.Task ProvisionQueues(ServiceControl.Transports.TransportSettings transportSettings, System.Collections.Generic.IEnumerable additionalQueues); + System.Threading.Tasks.Task ProvisionQueues(ServiceControl.Transports.TransportSettings transportSettings, System.Collections.Generic.IEnumerable additionalQueues, System.Threading.CancellationToken cancellationToken = default); string ToTransportQualifiedQueueName(string queueName); } public class QueueLengthEntry @@ -52,14 +52,14 @@ namespace ServiceControl.Transports protected virtual void AddTransportForPrimaryCore(Microsoft.Extensions.DependencyInjection.IServiceCollection services, ServiceControl.Transports.TransportSettings transportSettings) { } protected void ConfigureDefaultEndpointSettings(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings) { } protected abstract TTransport CreateTransport(ServiceControl.Transports.TransportSettings transportSettings, NServiceBus.TransportTransactionMode preferredTransactionMode = 1); - public System.Threading.Tasks.Task CreateTransportInfrastructure(string name, ServiceControl.Transports.TransportSettings transportSettings, NServiceBus.Transport.OnMessage onMessage = null, NServiceBus.Transport.OnError onError = null, System.Func onCriticalError = null, NServiceBus.TransportTransactionMode preferredTransactionMode = 1) { } + public System.Threading.Tasks.Task CreateTransportInfrastructure(string name, ServiceControl.Transports.TransportSettings transportSettings, NServiceBus.Transport.OnMessage onMessage = null, NServiceBus.Transport.OnError onError = null, System.Func onCriticalError = null, NServiceBus.TransportTransactionMode preferredTransactionMode = 1, System.Threading.CancellationToken cancellationToken = default) { } public void CustomizeAuditEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings) { } public void CustomizeMonitoringEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings) { } public void CustomizePrimaryEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, ServiceControl.Transports.TransportSettings transportSettings) { } protected abstract void CustomizeTransportForAuditEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TTransport transportDefinition, ServiceControl.Transports.TransportSettings transportSettings); protected abstract void CustomizeTransportForMonitoringEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TTransport transportDefinition, ServiceControl.Transports.TransportSettings transportSettings); protected abstract void CustomizeTransportForPrimaryEndpoint(NServiceBus.EndpointConfiguration endpointConfiguration, TTransport transportDefinition, ServiceControl.Transports.TransportSettings transportSettings); - public virtual System.Threading.Tasks.Task ProvisionQueues(ServiceControl.Transports.TransportSettings transportSettings, System.Collections.Generic.IEnumerable additionalQueues) { } + public virtual System.Threading.Tasks.Task ProvisionQueues(ServiceControl.Transports.TransportSettings transportSettings, System.Collections.Generic.IEnumerable additionalQueues, System.Threading.CancellationToken cancellationToken = default) { } public string ToTransportQualifiedQueueName(string queueName) { } protected virtual string ToTransportQualifiedQueueNameCore(string queueName) { } } @@ -113,8 +113,8 @@ namespace ServiceControl.Transports.BrokerThroughput public string MessageTransport { get; } public string? ScopeType { get; set; } public abstract ServiceControl.Transports.BrokerThroughput.KeyDescriptionPair[] Settings { get; } - public abstract System.Collections.Generic.IAsyncEnumerable GetQueueNames(System.Threading.CancellationToken cancellationToken); - public abstract System.Collections.Generic.IAsyncEnumerable GetThroughputPerDay(ServiceControl.Transports.BrokerThroughput.IBrokerQueue brokerQueue, System.DateOnly startDate, System.Threading.CancellationToken cancellationToken); + public abstract System.Collections.Generic.IAsyncEnumerable GetQueueNames(System.Threading.CancellationToken cancellationToken = default); + public abstract System.Collections.Generic.IAsyncEnumerable GetThroughputPerDay(ServiceControl.Transports.BrokerThroughput.IBrokerQueue brokerQueue, System.DateOnly startDate, System.Threading.CancellationToken cancellationToken = default); public bool HasInitialisationErrors(out string errorMessage) { } public void Initialize(System.Collections.ObjectModel.ReadOnlyDictionary settings) { } protected abstract void InitializeCore(System.Collections.ObjectModel.ReadOnlyDictionary settings); @@ -124,11 +124,11 @@ namespace ServiceControl.Transports.BrokerThroughput "Success", "Errors", "Diagnostics"})] - public System.Threading.Tasks.Task, string>> TestConnection(System.Threading.CancellationToken cancellationToken) { } + public System.Threading.Tasks.Task, string>> TestConnection(System.Threading.CancellationToken cancellationToken = default) { } [return: System.Runtime.CompilerServices.TupleElementNames(new string[] { "Success", "Errors"})] - protected abstract System.Threading.Tasks.Task>> TestConnectionCore(System.Threading.CancellationToken cancellationToken); + protected abstract System.Threading.Tasks.Task>> TestConnectionCore(System.Threading.CancellationToken cancellationToken = default); } public class DefaultBrokerQueue : ServiceControl.Transports.BrokerThroughput.IBrokerQueue { @@ -151,8 +151,8 @@ namespace ServiceControl.Transports.BrokerThroughput string MessageTransport { get; } string? ScopeType { get; } ServiceControl.Transports.BrokerThroughput.KeyDescriptionPair[] Settings { get; } - System.Collections.Generic.IAsyncEnumerable GetQueueNames(System.Threading.CancellationToken cancellationToken); - System.Collections.Generic.IAsyncEnumerable GetThroughputPerDay(ServiceControl.Transports.BrokerThroughput.IBrokerQueue brokerQueue, System.DateOnly startDate, System.Threading.CancellationToken cancellationToken); + System.Collections.Generic.IAsyncEnumerable GetQueueNames(System.Threading.CancellationToken cancellationToken = default); + System.Collections.Generic.IAsyncEnumerable GetThroughputPerDay(ServiceControl.Transports.BrokerThroughput.IBrokerQueue brokerQueue, System.DateOnly startDate, System.Threading.CancellationToken cancellationToken = default); bool HasInitialisationErrors(out string errorMessage); void Initialize(System.Collections.ObjectModel.ReadOnlyDictionary settings); string SanitizeEndpointName(string endpointName); @@ -161,7 +161,7 @@ namespace ServiceControl.Transports.BrokerThroughput "Success", "Errors", "Diagnostics"})] - System.Threading.Tasks.Task, string>> TestConnection(System.Threading.CancellationToken cancellationToken); + System.Threading.Tasks.Task, string>> TestConnection(System.Threading.CancellationToken cancellationToken = default); } public readonly struct KeyDescriptionPair { diff --git a/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs b/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs index f31fe1a75e..a1fca88d13 100644 --- a/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs +++ b/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs @@ -8,6 +8,8 @@ public class BasicEndpointSetup : IEndpointSetupTemplate { +#pragma warning disable PS0018 // IEndpointSetupTemplate declares this without a CancellationToken +#pragma warning disable PS0013 // IEndpointSetupTemplate declares the callback as Func public async Task GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomization, Func configurationBuilderCustomization) @@ -27,5 +29,7 @@ public async Task GetConfiguration(RunDescriptor runDescr return endpointConfiguration; } +#pragma warning restore PS0013 +#pragma warning restore PS0018 } } \ No newline at end of file diff --git a/src/ServiceControl.Transports.Tests/Learning/TransportTestsConfiguration.cs b/src/ServiceControl.Transports.Tests/Learning/TransportTestsConfiguration.cs index c2d01ee3d3..caef32d208 100644 --- a/src/ServiceControl.Transports.Tests/Learning/TransportTestsConfiguration.cs +++ b/src/ServiceControl.Transports.Tests/Learning/TransportTestsConfiguration.cs @@ -2,13 +2,14 @@ { using System; using System.IO; + using System.Threading; using System.Threading.Tasks; using ServiceControl.Transports; using ServiceControl.Transports.Learning; partial class TransportTestsConfiguration { - public Task Configure() + public Task Configure(CancellationToken cancellationToken = default) { basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $".test{Path.GetRandomFileName()}"); @@ -29,7 +30,7 @@ public Task Configure() public ITransportCustomization TransportCustomization { get; private set; } - public Task Cleanup() + public Task Cleanup(CancellationToken cancellationToken = default) { if (Directory.Exists(basePath)) { diff --git a/src/ServiceControl.Transports.Tests/TestDispatcherExtensions.cs b/src/ServiceControl.Transports.Tests/TestDispatcherExtensions.cs index 23608ffead..e4bd7a0caa 100644 --- a/src/ServiceControl.Transports.Tests/TestDispatcherExtensions.cs +++ b/src/ServiceControl.Transports.Tests/TestDispatcherExtensions.cs @@ -10,14 +10,14 @@ static class TestDispatcherExtensions { - public static Task SendTestMessage(this IMessageDispatcher dispatcher, string queue, string content, ITransportCustomization transportCustomization) + public static Task SendTestMessage(this IMessageDispatcher dispatcher, string queue, string content, ITransportCustomization transportCustomization, CancellationToken cancellationToken = default) { var transportOperation = new TransportOperation( new OutgoingMessage(Guid.NewGuid().ToString(), [], Encoding.UTF8.GetBytes(content)), new UnicastAddressTag(transportCustomization.ToTransportQualifiedQueueName(queue)), []); - return dispatcher.Dispatch(new TransportOperations(transportOperation), new TransportTransaction(), CancellationToken.None); + return dispatcher.Dispatch(new TransportOperations(transportOperation), new TransportTransaction(), cancellationToken); } } } \ No newline at end of file diff --git a/src/ServiceControl.Transports.Tests/TransportTestFixture.cs b/src/ServiceControl.Transports.Tests/TransportTestFixture.cs index c676bb4570..024c84a9c1 100644 --- a/src/ServiceControl.Transports.Tests/TransportTestFixture.cs +++ b/src/ServiceControl.Transports.Tests/TransportTestFixture.cs @@ -44,7 +44,7 @@ public virtual async Task Setup() await configuration.Configure(); - dispatcherTransportInfrastructure = await CreateDispatcherTransportInfrastructure(); + dispatcherTransportInfrastructure = await CreateDispatcherTransportInfrastructure(testCancellationTokenSource.Token); } [TearDown] @@ -98,7 +98,7 @@ protected TaskCompletionSource CreateTaskCompletionSource() protected TransportTestsConfiguration configuration; - protected async Task StartQueueLengthProvider(string queueName, Action onQueueLengthReported) + protected async Task StartQueueLengthProvider(string queueName, Action onQueueLengthReported, CancellationToken cancellationToken = default) { // The transport test fixture abuses the transport seam as if it was stateless can but it isn't really // currently working around by creating a service collection per start call and then disposing the provider @@ -122,7 +122,7 @@ protected async Task StartQueueLengthProvider(string queueName var serviceProvider = serviceCollection.BuildServiceProvider(); queueLengthProvider = serviceProvider.GetRequiredService(); - await queueLengthProvider.StartAsync(CancellationToken.None); + await queueLengthProvider.StartAsync(cancellationToken); queueLengthProvider.TrackEndpointInputQueue(new EndpointToQueueMapping(queueName, queueName)); return new QueueLengthProviderScope(serviceProvider); @@ -140,7 +140,8 @@ public async ValueTask DisposeAsync() protected async Task StartQueueIngestor( string queueName, OnMessage onMessage, - OnError onError) + OnError onError, + CancellationToken cancellationToken = default) { var transportSettings = new TransportSettings { @@ -154,18 +155,19 @@ protected async Task StartQueueIngestor( transportSettings, onMessage, onError, - (_, __) => + (_, __, ___) => { Assert.Fail("There should be no critical errors"); return Task.CompletedTask; - }); + }, + cancellationToken: cancellationToken); queueIngestor = transportInfrastructure.Receivers[queueName]; - await queueIngestor.StartReceive(); + await queueIngestor.StartReceive(cancellationToken); } - protected Task ProvisionQueues(string queueName, string errorQueue, IEnumerable additionalQueues) + protected Task ProvisionQueues(string queueName, string errorQueue, IEnumerable additionalQueues, CancellationToken cancellationToken = default) { var transportSettings = new TransportSettings { @@ -175,10 +177,10 @@ protected Task ProvisionQueues(string queueName, string errorQueue, IEnumerable< MaxConcurrency = 1 }; - return configuration.TransportCustomization.ProvisionQueues(transportSettings, additionalQueues); + return configuration.TransportCustomization.ProvisionQueues(transportSettings, additionalQueues, cancellationToken); } - protected Task CreateTestQueue(string queueName) + protected Task CreateTestQueue(string queueName, CancellationToken cancellationToken = default) { var transportSettings = new TransportSettings { @@ -187,12 +189,12 @@ protected Task CreateTestQueue(string queueName) MaxConcurrency = 1 }; - return configuration.TransportCustomization.ProvisionQueues(transportSettings, []); + return configuration.TransportCustomization.ProvisionQueues(transportSettings, [], cancellationToken); } protected static TimeSpan TestTimeout = TimeSpan.FromMinutes(5); - protected async Task SendAndReceiveMessages(string queueName, int numMessagesToIngest) + protected async Task SendAndReceiveMessages(string queueName, int numMessagesToIngest, CancellationToken cancellationToken = default) { TaskCompletionSource onMessagesProcessed = CreateTaskCompletionSource(); int numMessagesIngested = 0; @@ -214,11 +216,12 @@ await StartQueueIngestor( { Assert.Fail("There should be no errors"); return Task.FromResult(ErrorHandleResult.Handled); - }); + }, + cancellationToken); for (int i = 0; i < numMessagesToIngest; i++) { - await Dispatcher.SendTestMessage(queueName, $"message{i}", configuration.TransportCustomization); + await Dispatcher.SendTestMessage(queueName, $"message{i}", configuration.TransportCustomization, cancellationToken); } bool allMessagesProcessed = await onMessagesProcessed.Task; @@ -226,18 +229,18 @@ await StartQueueIngestor( if (queueIngestor != null) { - await queueIngestor.StopReceive(); + await queueIngestor.StopReceive(cancellationToken); queueIngestor = null; } if (transportInfrastructure != null) { - await transportInfrastructure.Shutdown(); + await transportInfrastructure.Shutdown(cancellationToken); transportInfrastructure = null; } } - async Task CreateDispatcherTransportInfrastructure() + async Task CreateDispatcherTransportInfrastructure(CancellationToken cancellationToken) { var transportSettings = new TransportSettings { @@ -246,7 +249,7 @@ async Task CreateDispatcherTransportInfrastructure() MaxConcurrency = 1 }; - return await configuration.TransportCustomization.CreateTransportInfrastructure("TransportTestDispatcher", transportSettings); + return await configuration.TransportCustomization.CreateTransportInfrastructure("TransportTestDispatcher", transportSettings, cancellationToken: cancellationToken); } string queueSuffix; diff --git a/src/ServiceControl.Transports/.editorconfig b/src/ServiceControl.Transports/.editorconfig index 6d6299e825..ff993b49bb 100644 --- a/src/ServiceControl.Transports/.editorconfig +++ b/src/ServiceControl.Transports/.editorconfig @@ -2,11 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0. -# They are scheduled work, not accepted exceptions: remove a line once this project has no -# violations of that rule left, and never add a rule back to this list. -dotnet_diagnostic.PS0003.severity = none -dotnet_diagnostic.PS0013.severity = none -dotnet_diagnostic.PS0018.severity = none -dotnet_diagnostic.PS0019.severity = none diff --git a/src/ServiceControl.Transports/AbstractQueueLengthProvider.cs b/src/ServiceControl.Transports/AbstractQueueLengthProvider.cs index a6402e127e..5dbb033bbc 100644 --- a/src/ServiceControl.Transports/AbstractQueueLengthProvider.cs +++ b/src/ServiceControl.Transports/AbstractQueueLengthProvider.cs @@ -12,7 +12,7 @@ public abstract class AbstractQueueLengthProvider(TransportSettings settings, Ac protected string ConnectionString { get; } = settings.ConnectionString; - public override async Task StartAsync(CancellationToken cancellationToken) + public override async Task StartAsync(CancellationToken cancellationToken = default) { // BackgroundService in .NET awaits the returned task to be completed. Queue providers might be doing // some heavy lifting before yielding so we are forcing things to be offloaded here by default. diff --git a/src/ServiceControl.Transports/BrokerThroughput/BrokerThroughputQuery.cs b/src/ServiceControl.Transports/BrokerThroughput/BrokerThroughputQuery.cs index f5c1ee70b4..7f4b6c85c0 100644 --- a/src/ServiceControl.Transports/BrokerThroughput/BrokerThroughputQuery.cs +++ b/src/ServiceControl.Transports/BrokerThroughput/BrokerThroughputQuery.cs @@ -47,9 +47,9 @@ public void Initialize(ReadOnlyDictionary settings) protected abstract void InitializeCore(ReadOnlyDictionary settings); public abstract IAsyncEnumerable GetThroughputPerDay(IBrokerQueue brokerQueue, DateOnly startDate, - CancellationToken cancellationToken); + CancellationToken cancellationToken = default); - public abstract IAsyncEnumerable GetQueueNames(CancellationToken cancellationToken); + public abstract IAsyncEnumerable GetQueueNames(CancellationToken cancellationToken = default); public Dictionary Data { get; set; } = []; public string MessageTransport => transport; @@ -57,7 +57,7 @@ public abstract IAsyncEnumerable GetThroughputPerDay(IBrokerQue public abstract KeyDescriptionPair[] Settings { get; } public async Task<(bool Success, List Errors, string Diagnostics)> TestConnection( - CancellationToken cancellationToken) + CancellationToken cancellationToken = default) { var sb = new StringBuilder(); if (InitialiseErrors.Count > 0) @@ -97,6 +97,10 @@ public abstract IAsyncEnumerable GetThroughputPerDay(IBrokerQue return (success, errors, sb.ToString()); } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } catch (Exception ex) { logger.LogError(ex, "Test connection failed"); @@ -111,7 +115,7 @@ public abstract IAsyncEnumerable GetThroughputPerDay(IBrokerQue } protected abstract Task<(bool Success, List Errors)> - TestConnectionCore(CancellationToken cancellationToken); + TestConnectionCore(CancellationToken cancellationToken = default); public virtual string SanitizeEndpointName(string endpointName) => endpointName; diff --git a/src/ServiceControl.Transports/BrokerThroughput/IBrokerThroughputQuery.cs b/src/ServiceControl.Transports/BrokerThroughput/IBrokerThroughputQuery.cs index 34bc5afa7d..5864823749 100644 --- a/src/ServiceControl.Transports/BrokerThroughput/IBrokerThroughputQuery.cs +++ b/src/ServiceControl.Transports/BrokerThroughput/IBrokerThroughputQuery.cs @@ -12,13 +12,13 @@ public interface IBrokerThroughputQuery bool HasInitialisationErrors(out string errorMessage); void Initialize(ReadOnlyDictionary settings); IAsyncEnumerable GetThroughputPerDay(IBrokerQueue brokerQueue, DateOnly startDate, - CancellationToken cancellationToken); - IAsyncEnumerable GetQueueNames(CancellationToken cancellationToken); + CancellationToken cancellationToken = default); + IAsyncEnumerable GetQueueNames(CancellationToken cancellationToken = default); Dictionary Data { get; } string MessageTransport { get; } string? ScopeType { get; } KeyDescriptionPair[] Settings { get; } - Task<(bool Success, List Errors, string Diagnostics)> TestConnection(CancellationToken cancellationToken); + Task<(bool Success, List Errors, string Diagnostics)> TestConnection(CancellationToken cancellationToken = default); string SanitizeEndpointName(string endpointName); string SanitizedEndpointNameCleanser(string endpointName); } \ No newline at end of file diff --git a/src/ServiceControl.Transports/TransportCustomization.cs b/src/ServiceControl.Transports/TransportCustomization.cs index 720d00ff5f..a03fcb2ee1 100644 --- a/src/ServiceControl.Transports/TransportCustomization.cs +++ b/src/ServiceControl.Transports/TransportCustomization.cs @@ -22,10 +22,10 @@ public interface ITransportCustomization void CustomizeMonitoringEndpoint(EndpointConfiguration endpointConfiguration, TransportSettings transportSettings); void AddTransportForMonitoring(IServiceCollection services, TransportSettings transportSettings); - Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues); + Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues, CancellationToken cancellationToken = default); string ToTransportQualifiedQueueName(string queueName); - Task CreateTransportInfrastructure(string name, TransportSettings transportSettings, OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly); + Task CreateTransportInfrastructure(string name, TransportSettings transportSettings, OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly, CancellationToken cancellationToken = default); } public abstract class TransportCustomization : ITransportCustomization where TTransport : TransportDefinition @@ -123,7 +123,7 @@ protected void ConfigureDefaultEndpointSettings(EndpointConfiguration endpointCo protected virtual string ToTransportQualifiedQueueNameCore(string queueName) => queueName; - public virtual async Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues) + public virtual async Task ProvisionQueues(TransportSettings transportSettings, IEnumerable additionalQueues, CancellationToken cancellationToken = default) { // For queue provisioning MaxConcurrency is not relevant. Settings it to 1 to avoid null checks transportSettings.MaxConcurrency ??= 1; @@ -155,21 +155,21 @@ public virtual async Task ProvisionQueues(TransportSettings transportSettings, I .Distinct() .ToArray(); - var transportInfrastructure = await transport.Initialize(hostSettings, receivers, additionalQueuesToProvision); - await transportInfrastructure.Shutdown(); + var transportInfrastructure = await transport.Initialize(hostSettings, receivers, additionalQueuesToProvision, cancellationToken); + await transportInfrastructure.Shutdown(cancellationToken); } - public async Task CreateTransportInfrastructure(string name, TransportSettings transportSettings, OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly) + public async Task CreateTransportInfrastructure(string name, TransportSettings transportSettings, OnMessage onMessage = null, OnError onError = null, Func onCriticalError = null, TransportTransactionMode preferredTransactionMode = TransportTransactionMode.ReceiveOnly, CancellationToken cancellationToken = default) { var transport = CreateTransport(transportSettings, preferredTransactionMode); - onCriticalError ??= (_, __) => Task.CompletedTask; + onCriticalError ??= (_, __, ___) => Task.CompletedTask; var hostSettings = new HostSettings( name, $"TransportInfrastructure for {name}", new StartupDiagnosticEntries(), - (msg, exception, cancellationToken) => Task.Run(() => onCriticalError(msg, exception), cancellationToken), + (msg, exception, criticalErrorCancellationToken) => Task.Run(() => onCriticalError(msg, exception, criticalErrorCancellationToken), criticalErrorCancellationToken), false, null); //null means "not hosted by core", transport SHOULD adjust accordingly to not assume things @@ -186,7 +186,7 @@ public async Task CreateTransportInfrastructure(string receivers = []; } - var transportInfrastructure = await transport.Initialize(hostSettings, receivers, new[] { ToTransportQualifiedQueueNameCore(transportSettings.ErrorQueue) }); + var transportInfrastructure = await transport.Initialize(hostSettings, receivers, new[] { ToTransportQualifiedQueueNameCore(transportSettings.ErrorQueue) }, cancellationToken); if (createReceiver) { @@ -196,7 +196,7 @@ public async Task CreateTransportInfrastructure(string } var transportInfrastructureReceiver = transportInfrastructure.Receivers[name]; - await transportInfrastructureReceiver.Initialize(new PushRuntimeSettings(transportSettings.MaxConcurrency.Value), onMessage, onError, CancellationToken.None); + await transportInfrastructureReceiver.Initialize(new PushRuntimeSettings(transportSettings.MaxConcurrency.Value), onMessage, onError, cancellationToken); } return transportInfrastructure; diff --git a/src/ServiceControl/.editorconfig b/src/ServiceControl/.editorconfig index 0f304aa060..ff993b49bb 100644 --- a/src/ServiceControl/.editorconfig +++ b/src/ServiceControl/.editorconfig @@ -2,10 +2,3 @@ # Justification: ServiceControl app has no synchronization context dotnet_diagnostic.CA2007.severity = none - -# Blocked on the transport abstraction. TransportCustomization.CreateTransportInfrastructure takes -# Func for onCriticalError, so the critical-error path here cannot carry a -# token until that signature gains one in the transports phase. -[{Operations/ErrorIngestion.cs,Operations/ErrorIngestionFaultPolicy.cs,Operations/ImportFailureCircuitBreaker.cs}] -dotnet_diagnostic.PS0013.severity = none -dotnet_diagnostic.PS0018.severity = none diff --git a/src/ServiceControl/Hosting/Commands/SetupCommand.cs b/src/ServiceControl/Hosting/Commands/SetupCommand.cs index 4ded1e9648..a719eaa8eb 100644 --- a/src/ServiceControl/Hosting/Commands/SetupCommand.cs +++ b/src/ServiceControl/Hosting/Commands/SetupCommand.cs @@ -47,7 +47,7 @@ public override async Task Execute(HostArguments args, Settings settings, Cancel transportSettings.RunCustomChecks = false; var transportCustomization = TransportFactory.Create(transportSettings); - await transportCustomization.ProvisionQueues(transportSettings, componentSetupContext.Queues); + await transportCustomization.ProvisionQueues(transportSettings, componentSetupContext.Queues, cancellationToken); } await using (var scope = host.Services.CreateAsyncScope()) diff --git a/src/ServiceControl/Operations/ErrorIngestion.cs b/src/ServiceControl/Operations/ErrorIngestion.cs index 834b16c517..a483a94991 100644 --- a/src/ServiceControl/Operations/ErrorIngestion.cs +++ b/src/ServiceControl/Operations/ErrorIngestion.cs @@ -221,7 +221,8 @@ async Task SetUpAndStartInfrastructure(CancellationToken cancellationToken) OnMessage, errorHandlingPolicy.OnError, OnCriticalError, - TransportTransactionMode.ReceiveOnly + TransportTransactionMode.ReceiveOnly, + cancellationToken ); messageReceiver = transportInfrastructure.Receivers[errorQueue]; @@ -304,10 +305,10 @@ async Task OnMessage(MessageContext messageContext, CancellationToken cancellati await taskCompletionSource.Task; } - Task OnCriticalError(string failure, Exception exception) + Task OnCriticalError(string failure, Exception exception, CancellationToken cancellationToken) { logger.LogCritical(exception, "OnCriticalError. '{FailureMessage}'", failure); - return watchdog.OnFailure(failure); + return watchdog.OnFailure(failure, cancellationToken); } async Task EnsureStopped(CancellationToken cancellationToken) diff --git a/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs b/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs index 93249bca49..0e5fb7b1d0 100644 --- a/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs +++ b/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs @@ -21,7 +21,7 @@ class ErrorIngestionFaultPolicy ImportFailureCircuitBreaker failureCircuitBreaker; - public ErrorIngestionFaultPolicy(IFailedErrorImportDataStore store, LoggingSettings loggingSettings, Func onCriticalError, ILogger logger) + public ErrorIngestionFaultPolicy(IFailedErrorImportDataStore store, LoggingSettings loggingSettings, Func onCriticalError, ILogger logger) { this.store = store; this.logger = logger; diff --git a/src/ServiceControl/Operations/ImportFailureCircuitBreaker.cs b/src/ServiceControl/Operations/ImportFailureCircuitBreaker.cs index 14d5192576..8d53692621 100644 --- a/src/ServiceControl/Operations/ImportFailureCircuitBreaker.cs +++ b/src/ServiceControl/Operations/ImportFailureCircuitBreaker.cs @@ -7,7 +7,7 @@ class ImportFailureCircuitBreaker : IDisposable { - public ImportFailureCircuitBreaker(Func onCriticalError) + public ImportFailureCircuitBreaker(Func onCriticalError) { this.onCriticalError = onCriticalError; timer = new Timer(_ => FlushHistory(), null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(20)); @@ -28,11 +28,13 @@ public void Increment(Exception lastException) var result = Interlocked.Increment(ref failureCount); if (result > 50) { - _ = Task.Run(() => onCriticalError("Failed to import too many times", lastException)); + // Not cancellable: the notification exists to trigger shutdown, so the token + // that shutdown cancels must not be able to suppress it. + _ = Task.Run(() => onCriticalError("Failed to import too many times", lastException, CancellationToken.None), CancellationToken.None); } } - Func onCriticalError; + Func onCriticalError; Timer timer; long failureCount; } diff --git a/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs b/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs index e2bf531c92..2c4d975e6a 100644 --- a/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs +++ b/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs @@ -40,7 +40,7 @@ ILogger logger public async Task StartAsync(CancellationToken cancellationToken = default) { - transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(InputAddress, transportSettings, Handle, faultManager.OnError, (_, __) => Task.CompletedTask, TransportTransactionMode.SendsAtomicWithReceive); + transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(InputAddress, transportSettings, Handle, faultManager.OnError, (_, __, ___) => Task.CompletedTask, TransportTransactionMode.SendsAtomicWithReceive, cancellationToken); messageReceiver = transportInfrastructure.Receivers[InputAddress]; messageDispatcher = transportInfrastructure.Dispatcher;