V12: Suppress execution context flow when queuing email task #14571
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.
Suppresses the execution context flow when queuing a task for sending notification emails. This is required because otherwise, the execution context would leak into the async thread that won't be joined.
This caused issues when trying to replace the
IEmailSender
with a different implementation that creates a scope since the execution context was flowed, it gets added to the same scope stack as the other thread, leading to race conditions that would throw errors because a child scope on the other thread wasn't disposed. This should no longer happen.It looks like there's a lot of changes in the PR, but all I did was wrapping the implementation of
NotificationService.Process
in ausing (ExecutionContext.SuppressFlow())
block.Testing
Since this is essentially a race condition it's pretty hard to test, but I was able to reproduce the issue somewhat reliably with the following approach (Thanks to the heartcore team for the test setup and heads up 馃挭):
IEmailSender
that callsUserService.GetByEmail
(see below for example)ConfigureServices
with:services.Replace(ServiceDescriptor.Singleton<IEmailSender, HeadlessEmailSender>());
Save and publish
as the first actionThis will throw a
System.InvalidOperationException
, not all the time, but more often than not.After checking out this branch the error should no longer occur.
Code snippet: