-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Start each request on fresh ExecutionContext #14146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cac6423
to
a56d21e
Compare
113f621
to
5fc4604
Compare
Cleaned up the encapsulation |
Since we are calling an extra async method anyway; realised it could be greatly simplified. (ignore whitespace) |
|
||
KestrelEventSource.Log.RequestStop(this); | ||
private async ValueTask ProcessRequest<TContext>(IHttpApplication<TContext> application) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Task
is a more performant return here than ValueTask
and will allocate the same; i.e none in the sync completion and the async box in the async wait scenario (subject to dotnet/coreclr#26310 when ValueTask
becomes better as it doesn't allocate in async)
So much nicer! We probably still want to take the tests from #14027 though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One subtle difference between this and #14027 is that the Response.OnCompleted callback will run with the same ExecutionContext as the middleware if the middleware isn't "async". With #14027, the Response.OnCompleted gets a fresh ExecutionContext no matter what. I think this probably is fine though as long as we add a test and don't change behavior.
Added tests
Also added compat test and commented it as such https://github.com/aspnet/AspNetCore/pull/14146/files#diff-d47b9baa7ec5338570136a89e5e8a4deR441-R444 public async Task ExecutionContextMutationsOfValueTypeFlowThroughNonAsyncEvents()
{
// Note: This test is for future compat behviour checking
// to ensure non-async OnStarting/OnCompleted flow AsyncLocal changes out |
We need to run performance tests |
Don't think it will be great :( However... might as well make the OnStarting/OnComplete async as they won't regress performance; since normally aren't called? |
Changed it to flow normally for non-async events also; since they won't run if you haven't defined any so it shouldn't effect performance if you choose not to use them. |
@halter73 are you good to merge this in for 5.0? |
Not without performance tests. |
Is that auto perf test ci thing working? #16999 (seems to be having versioning issues) |
Maybe we can use the in memory perf tests |
/azp run |
Azure Pipelines successfully started running 2 pipeline(s). |
@aspnet-hello benchmark |
Starting 'Default' pipelined plaintext benchmark with session ID 'f4894b6a4a114f84ae664bf363da98e7'. This could take up to 30 minutes... |
Baseline
PR
|
@davidfowl are you good with the perf on this? I'd like to close it out and preferably by merging it ;P |
Ping @davidfowl @halter73 |
Hearing nothing from @davidfowl, I'm going to go ahead and tell @halter73 he can merge away ;). |
Merge it we can measure things now |
5911157
to
116424d
Compare
Rebased |
@aspnet-hello benchmark |
Starting 'Default' pipelined plaintext benchmark with session ID '256b16f3fd1a44faa4552049ed33f796'. This could take up to 30 minutes... |
Baseline
PR
|
Fixed by #14146 which starts each request on a fresh ExecutionContext
Fixed by #14146 which starts each request on a fresh ExecutionContext
I have observed an issue (on AspNetCore version 3.1.13) with AsyncLocal context being leaked between requests. (Never in parallel, the Context from one request which finishes appears to be present at the start of a subsequent one, and so on in a chain of many requests). I have not attempted (yet) to reproduce this locally, but have observed it reliably in our Production systems. I have seen this issue is closed now: #13991 A little more context - the AsyncLocal state tracked in our case gets initialised in Log sink which is NOT in an Async method. (The only reason I mention that is that some comments in the linked issue refer to the method setting the AsyncLocal state should be async. Any input gratefully received - hope this isn't wasting your time! (I can open this as a new issue if that's best) |
Hi @BIOsborne. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
@BIOsborne this fix is in .NET 5 and has not been backported to 3.1. |
Hi @alefranz. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Thanks @alefranz for quick reply - good to know. |
Hi @BIOsborne. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Check with Hide Whitespace on; as indents changed.
Fixes #13991
Per request allocations for Plaintext sample remains the same
Allocations for 17k requests across 256 connections