Repository navigation
Continue cancellation token propagation in persistence layer - #5731
Merged
Merged
Conversation
rbev
approved these changes
Aug 11, 2026
Expands the application of optional `CancellationToken` parameters to asynchronous methods across all persistence data store interfaces and their EFCore and RavenDB implementations. This allows for more granular control over cancelling long-running database operations and further addresses cancellation-related static analysis warnings.
johnsimons
force-pushed
the
john/cancel_part3
branch
from
August 11, 2026 07:17
441dd8b to
08d47f4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Covers two interface groups together, because
ErrorMessagesDataStoreimplements all four of their interfaces and is better converted in one pass than left half-done:IFailedMessageQueryDataStore(7),IMessagesViewDataStore(5),IQueueAddressStore(1)IFailedMessageLifecycleDataStore(5),IFailedMessageRetryDataStore(5)23 interface methods, both persisters, 15 host call sites, 3 test doubles. The highest actual payoff is
ServiceControl/CompositeViews, the scatter-gather HTTP fan-out to remote instances, where an abandoned request previously kept running to completion against every remote.Two things worth a reviewer's attention:
ProcessPendingRetries' callback becameFunc<string, CancellationToken, Task>(PS0013). The store owns the streaming loop, so it hands each iteration its own token. At the one real caller,MessageFailureResolvedHandler, that token is genuinely unused: NServiceBus'IPipelineContext.Sendoverloads deliberately take noCancellationToken(the token lives on the context). It is left unused rather than given an invented use.ReturnToSenderDequeuer.CaptureIfMessageSendingFails.OnError. It carried_ = cancellationToken;under a comment claiming the token could not be propagated "since it would require to change the data store APIs". The comment was already wrong, since the token was in use two lines below atdomainEvents.Raiseand in the catch filter.RevertRetrywas the last real gap and this closes it.DataStoreBase.ExecuteWithDbContextis deliberately left alone: the lambdas now close over the enclosingcancellationToken, so propagation is complete and correct with no blast radius. Changing itsFuncto carry the token would break lambda arity at roughly 40 stores and forceCancellationToken.Noneplaceholders in the ones not yet converted. Done last instead, it is a mechanical sweep over already-tokenised code.