Skip to content

Commit cbc2e7e

Browse files
committed
Continue cancellation token propagation in audit persistence layer
This change expands the consistent application of optional `CancellationToken` parameters to asynchronous methods within the audit persistence interfaces and their InMemory and RavenDB implementations. Cancellation tokens are now propagated to underlying asynchronous database calls and consuming services. This ensures proper cancellation of long-running operations and further reduces cancellation analyzer debt by removing suppressions from related `.editorconfig` files.
1 parent 6487555 commit cbc2e7e

26 files changed

Lines changed: 83 additions & 97 deletions

‎src/ServiceControl.Audit.Persistence.InMemory/.editorconfig‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,3 @@
22

33
# Justification: ServiceControl app has no synchronization context
44
dotnet_diagnostic.CA2007.severity = none
5-
6-
# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
7-
# They are scheduled work, not accepted exceptions: remove a line once this project has no
8-
# violations of that rule left, and never add a rule back to this list.
9-
dotnet_diagnostic.PS0003.severity = none
10-
dotnet_diagnostic.PS0018.severity = none

‎src/ServiceControl.Audit.Persistence.InMemory/InMemoryAttachmentsBodyStorage.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public InMemoryAttachmentsBodyStorage()
1616
messageBodies = [];
1717
}
1818

19-
public Task Store(string bodyId, string contentType, int bodySize, Stream bodyStream, CancellationToken cancellationToken)
19+
public Task Store(string bodyId, string contentType, int bodySize, Stream bodyStream, CancellationToken cancellationToken = default)
2020
{
2121
var messageBody = messageBodies.FirstOrDefault(w => w.BodyId == bodyId);
2222

@@ -44,7 +44,7 @@ public Task Store(string bodyId, string contentType, int bodySize, Stream bodySt
4444
return Task.CompletedTask;
4545
}
4646

47-
public async Task<StreamResult> TryFetch(string bodyId, CancellationToken cancellationToken)
47+
public async Task<StreamResult> TryFetch(string bodyId, CancellationToken cancellationToken = default)
4848
{
4949
var messageBody = messageBodies.FirstOrDefault(w => w.BodyId == bodyId);
5050

‎src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditDataStore.cs‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public InMemoryAuditDataStore(IBodyStorage bodyStorage)
2525
failedAuditImports = [];
2626
}
2727

28-
public async Task<QueryResult<SagaHistory>> QuerySagaHistoryById(Guid input, CancellationToken cancellationToken)
28+
public async Task<QueryResult<SagaHistory>> QuerySagaHistoryById(Guid input, CancellationToken cancellationToken = default)
2929
{
3030
var sagaHistory = sagaHistories.FirstOrDefault(w => w.SagaId == input);
3131

@@ -37,7 +37,7 @@ public async Task<QueryResult<SagaHistory>> QuerySagaHistoryById(Guid input, Can
3737
return await Task.FromResult(new QueryResult<SagaHistory>(sagaHistory, new QueryStatsInfo(string.Empty, 1)));
3838
}
3939

40-
public async Task<QueryResult<IList<MessagesView>>> GetMessages(bool includeSystemMessages, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken)
40+
public async Task<QueryResult<IList<MessagesView>>> GetMessages(bool includeSystemMessages, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken = default)
4141
{
4242
var matched = messageViews
4343
.Where(w => (!w.IsSystemMessage || includeSystemMessages) &&
@@ -48,7 +48,7 @@ public async Task<QueryResult<IList<MessagesView>>> GetMessages(bool includeSyst
4848
return await Task.FromResult(new QueryResult<IList<MessagesView>>(matched, new QueryStatsInfo(string.Empty, matched.Count)));
4949
}
5050

51-
public async Task<QueryResult<IList<MessagesView>>> QueryMessages(string keyword, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken)
51+
public async Task<QueryResult<IList<MessagesView>>> QueryMessages(string keyword, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken = default)
5252
{
5353
var messages = GetMessageIdsMatchingQuery(keyword);
5454

@@ -60,7 +60,7 @@ public async Task<QueryResult<IList<MessagesView>>> QueryMessages(string keyword
6060
return await Task.FromResult(new QueryResult<IList<MessagesView>>(matched, new QueryStatsInfo(string.Empty, matched.Count())));
6161
}
6262

63-
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndpointAndKeyword(string endpoint, string keyword, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken)
63+
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndpointAndKeyword(string endpoint, string keyword, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken = default)
6464
{
6565
var messages = GetMessageIdsMatchingQuery(keyword);
6666

@@ -71,7 +71,7 @@ public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndp
7171
return await Task.FromResult(new QueryResult<IList<MessagesView>>(matched, new QueryStatsInfo(string.Empty, matched.Count)));
7272
}
7373

74-
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndpoint(bool includeSystemMessages, string endpointName, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken)
74+
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndpoint(bool includeSystemMessages, string endpointName, PagingInfo pagingInfo, SortInfo sortInfo, DateTimeRange timeSentRange, CancellationToken cancellationToken = default)
7575
{
7676
var matched = messageViews.Where(w => w.ReceivingEndpoint.Name == endpointName &&
7777
(timeSentRange == null || !timeSentRange.From.HasValue || w.TimeSent >= timeSentRange.From.Value) &&
@@ -80,15 +80,15 @@ public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByReceivingEndp
8080
return await Task.FromResult(new QueryResult<IList<MessagesView>>(matched, new QueryStatsInfo(string.Empty, matched.Count)));
8181
}
8282

83-
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByConversationId(string conversationId, PagingInfo pagingInfo, SortInfo sortInfo, CancellationToken cancellationToken)
83+
public async Task<QueryResult<IList<MessagesView>>> QueryMessagesByConversationId(string conversationId, PagingInfo pagingInfo, SortInfo sortInfo, CancellationToken cancellationToken = default)
8484
{
8585
var matched = messageViews.Where(w => w.ConversationId == conversationId).ToList();
8686
return await Task.FromResult(new QueryResult<IList<MessagesView>>(matched, new QueryStatsInfo(string.Empty, matched.Count)));
8787
}
8888

89-
public async Task<MessageBodyView> GetMessageBody(string messageId, CancellationToken cancellationToken)
89+
public async Task<MessageBodyView> GetMessageBody(string messageId, CancellationToken cancellationToken = default)
9090
{
91-
var result = await GetMessageBodyFromMetadata(messageId);
91+
var result = await GetMessageBodyFromMetadata(messageId, cancellationToken);
9292

9393
if (!result.Found)
9494
{
@@ -144,7 +144,7 @@ async Task<MessageBodyView> GetMessageBodyFromAttachments(string messageId, Canc
144144
return MessageBodyView.NotFound();
145145
}
146146

147-
Task<MessageBodyView> GetMessageBodyFromMetadata(string messageId)
147+
Task<MessageBodyView> GetMessageBodyFromMetadata(string messageId, CancellationToken cancellationToken)
148148
{
149149
var message = processedMessages.FirstOrDefault(pm => (pm.MessageMetadata["MessageId"] as string) == messageId);
150150

@@ -171,7 +171,7 @@ Task<MessageBodyView> GetMessageBodyFromMetadata(string messageId)
171171
return Task.FromResult(MessageBodyView.FromString(body, contentType, bodySize, messageId));
172172
}
173173

174-
public Task<QueryResult<IList<AuditCount>>> QueryAuditCounts(string endpointName, CancellationToken cancellationToken)
174+
public Task<QueryResult<IList<AuditCount>>> QueryAuditCounts(string endpointName, CancellationToken cancellationToken = default)
175175
{
176176
var results = messageViews
177177
.Where(m => m.ReceivingEndpoint.Name == endpointName && !m.IsSystemMessage)
@@ -187,7 +187,7 @@ public Task<QueryResult<IList<AuditCount>>> QueryAuditCounts(string endpointName
187187
return Task.FromResult(new QueryResult<IList<AuditCount>>(results, QueryStatsInfo.Zero));
188188
}
189189

190-
public Task SaveProcessedMessage(ProcessedMessage processedMessage)
190+
public Task SaveProcessedMessage(ProcessedMessage processedMessage, CancellationToken cancellationToken = default)
191191
{
192192
if (processedMessages.Any(pm => pm.Id == processedMessage.Id))
193193
{
@@ -200,7 +200,7 @@ public Task SaveProcessedMessage(ProcessedMessage processedMessage)
200200
return Task.CompletedTask;
201201
}
202202

203-
public Task SaveSagaSnapshot(SagaSnapshot sagaSnapshot)
203+
public Task SaveSagaSnapshot(SagaSnapshot sagaSnapshot, CancellationToken cancellationToken = default)
204204
{
205205
var sagaHistory = sagaHistories.SingleOrDefault(sh => sh.SagaId == sagaSnapshot.SagaId);
206206

@@ -240,7 +240,7 @@ object TryGet(Dictionary<string, object> metadata, string key)
240240
return null;
241241
}
242242

243-
public Task Setup() => Task.CompletedTask;
243+
public Task Setup(CancellationToken cancellationToken = default) => Task.CompletedTask;
244244

245245
List<MessagesView> messageViews;
246246
List<ProcessedMessage> processedMessages;

‎src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWork.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ class InMemoryAuditIngestionUnitOfWork(
1515
{
1616
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
1717

18-
public async Task RecordProcessedMessage(ProcessedMessage processedMessage, ReadOnlyMemory<byte> body, CancellationToken cancellationToken)
18+
public async Task RecordProcessedMessage(ProcessedMessage processedMessage, ReadOnlyMemory<byte> body, CancellationToken cancellationToken = default)
1919
{
2020
if (!body.IsEmpty)
2121
{
2222
await bodyStorageEnricher.StoreAuditMessageBody(body, processedMessage, cancellationToken);
2323
}
24-
await dataStore.SaveProcessedMessage(processedMessage);
24+
await dataStore.SaveProcessedMessage(processedMessage, cancellationToken);
2525
}
2626

27-
public Task RecordSagaSnapshot(SagaSnapshot sagaSnapshot, CancellationToken cancellationToken) => dataStore.SaveSagaSnapshot(sagaSnapshot);
27+
public Task RecordSagaSnapshot(SagaSnapshot sagaSnapshot, CancellationToken cancellationToken = default) => dataStore.SaveSagaSnapshot(sagaSnapshot, cancellationToken);
2828
}
2929
}

‎src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWorkFactory.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class InMemoryAuditIngestionUnitOfWorkFactory(InMemoryAuditDataStore dataStore, BodyStorageEnricher bodyStorageEnricher) : IAuditIngestionUnitOfWorkFactory
99
{
10-
public ValueTask<IAuditIngestionUnitOfWork> StartNew(int batchSize, CancellationToken cancellationToken)
10+
public ValueTask<IAuditIngestionUnitOfWork> StartNew(int batchSize, CancellationToken cancellationToken = default)
1111
{
1212
//The batchSize argument is ignored: the in-memory storage implementation doesn't support batching.
1313
return new ValueTask<IAuditIngestionUnitOfWork>(new InMemoryAuditIngestionUnitOfWork(dataStore, bodyStorageEnricher));

‎src/ServiceControl.Audit.Persistence.InMemory/InMemoryFailedAuditStorage.cs‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
class InMemoryFailedAuditStorage(InMemoryAuditDataStore dataStore) : IFailedAuditStorage
99
{
10-
public async Task ProcessFailedMessages(Func<FailedTransportMessage, Func<CancellationToken, Task>, CancellationToken, Task> onMessage, CancellationToken cancellationToken)
10+
public async Task ProcessFailedMessages(Func<FailedTransportMessage, Func<CancellationToken, Task>, CancellationToken, Task> onMessage, CancellationToken cancellationToken = default)
1111
{
12+
cancellationToken.ThrowIfCancellationRequested();
13+
1214
foreach (var failedMessage in dataStore.failedAuditImports)
1315
{
16+
cancellationToken.ThrowIfCancellationRequested();
1417
FailedTransportMessage transportMessage = failedMessage.Message;
1518

1619
await onMessage(transportMessage, _ => Task.CompletedTask, cancellationToken);
@@ -19,12 +22,17 @@ public async Task ProcessFailedMessages(Func<FailedTransportMessage, Func<Cancel
1922
dataStore.failedAuditImports.Clear();
2023
}
2124

22-
public Task SaveFailedAuditImport(FailedAuditImport message)
25+
public Task SaveFailedAuditImport(FailedAuditImport message, CancellationToken cancellationToken = default)
2326
{
27+
cancellationToken.ThrowIfCancellationRequested();
2428
dataStore.failedAuditImports.Add(message);
2529
return Task.CompletedTask;
2630
}
2731

28-
public Task<int> GetFailedAuditsCount() => Task.FromResult(dataStore.failedAuditImports.Count);
32+
public Task<int> GetFailedAuditsCount(CancellationToken cancellationToken = default)
33+
{
34+
cancellationToken.ThrowIfCancellationRequested();
35+
return Task.FromResult(dataStore.failedAuditImports.Count);
36+
}
2937
}
3038
}

‎src/ServiceControl.Audit.Persistence.RavenDB/.editorconfig‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,3 @@
22

33
# Justification: ServiceControl app has no synchronization context
44
dotnet_diagnostic.CA2007.severity = none
5-
6-
# Cancellation analyzer debt. These fire because Particular.Analyzers is no longer pinned to 0.9.0.
7-
# They are scheduled work, not accepted exceptions: remove a line once this project has no
8-
# violations of that rule left, and never add a rule back to this list.
9-
dotnet_diagnostic.PS0003.severity = none
10-
dotnet_diagnostic.PS0018.severity = none
11-
dotnet_diagnostic.PS0020.severity = none

‎src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
class DatabaseSetup(DatabaseConfiguration configuration)
2121
{
22-
public async Task Execute(IDocumentStore documentStore, CancellationToken cancellationToken)
22+
public async Task Execute(IDocumentStore documentStore, CancellationToken cancellationToken = default)
2323
{
2424
await CreateDatabase(documentStore, configuration.Name, cancellationToken);
2525

@@ -66,7 +66,7 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN
6666
await documentStore.Maintenance.Server.SendAsync(new ToggleDatabasesStateOperation(databaseName, false), cancellationToken);
6767
}
6868

69-
public static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentStore, CancellationToken cancellationToken)
69+
public static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentStore, CancellationToken cancellationToken = default)
7070
{
7171
// If the SagaDetailsIndex exists but does not have a .Take(50000), then we remove the current SagaDetailsIndex and
7272
// create a new one. If we do not remove the current one, then RavenDB will attempt to do a side-by-side migration.
@@ -82,7 +82,7 @@ public static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentSto
8282
}
8383
}
8484

85-
internal static async Task CreateIndexes(IDocumentStore documentStore, bool enableFreeTextSearch, CancellationToken cancellationToken)
85+
internal static async Task CreateIndexes(IDocumentStore documentStore, bool enableFreeTextSearch, CancellationToken cancellationToken = default)
8686
{
8787
await DeleteLegacySagaDetailsIndex(documentStore, cancellationToken);
8888

‎src/ServiceControl.Audit.Persistence.RavenDB/LicenseStatusCheck.cs‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ static class LicenseStatusCheck
1010
{
1111
record LicenseStatusFragment(string Id, string LicensedTo, string Status, bool Expired);
1212

13-
public static async Task WaitForLicenseOrThrow(IDocumentStore documentStore, CancellationToken cancellationToken)
13+
public static async Task WaitForLicenseOrThrow(IDocumentStore documentStore, CancellationToken cancellationToken = default)
1414
{
1515
var ravenConfiguredHttpClient = documentStore.GetRequestExecutor().HttpClient;
1616
var licenseCheckUrl = documentStore.Urls[0].TrimEnd('/') + "/license/status";
@@ -37,9 +37,19 @@ public static async Task WaitForLicenseOrThrow(IDocumentStore documentStore, Can
3737
await Task.Delay(200, cts.Token);
3838
}
3939
}
40-
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
40+
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
4141
{
42-
throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support");
42+
throw;
43+
}
44+
45+
catch (Exception exception)
46+
{
47+
if (exception is OperationCanceledException && cts.Token.IsCancellationRequested)
48+
{
49+
throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support");
50+
}
51+
52+
throw;
4353
}
4454
}
4555
}

‎src/ServiceControl.Audit.Persistence.RavenDB/RavenAttachmentsBodyStorage.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class RavenAttachmentsBodyStorage(
1212
int settingsMaxBodySizeToStore)
1313
: IBodyStorage
1414
{
15-
public Task Store(string bodyId, string contentType, int bodySize, Stream bodyStream, CancellationToken cancellationToken)
15+
public Task Store(string bodyId, string contentType, int bodySize, Stream bodyStream, CancellationToken cancellationToken = default)
1616
{
1717
if (bodySize > settingsMaxBodySizeToStore)
1818
{
@@ -23,7 +23,7 @@ public Task Store(string bodyId, string contentType, int bodySize, Stream bodySt
2323
.StoreAsync("body", bodyStream, contentType, cancellationToken);
2424
}
2525

26-
public async Task<StreamResult> TryFetch(string bodyId, CancellationToken cancellationToken)
26+
public async Task<StreamResult> TryFetch(string bodyId, CancellationToken cancellationToken = default)
2727
{
2828
using var session = await sessionProvider.OpenSession(cancellationToken: cancellationToken);
2929
var result = await session.Advanced.Attachments.GetAsync($"MessageBodies/{bodyId}", "body", cancellationToken);

0 commit comments

Comments
 (0)