Skip to content
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

suppress ExecutionContext by default in TestServer #10094

Merged
merged 9 commits into from
May 10, 2019

Conversation

analogrelay
Copy link
Contributor

fixes #7975

Currently, the ExecutionContext flows from client to server in TestServer. This seems odd because the server should be a separate instance. Also, it causes problems when you are running two different apps through TestServer (such as when you are testing IdentityServer and such). This change changes TestServer's client logic to force a new ExecutionContext when issuing HTTP requests.

There is a PreserveExecutionContext property to turn the old behavior back on. Also I had to modify where IHttpApplication.CreateContext is called since that's what sets the IHttpContextAccessor. If it's set before we dispatch to the thread pool (thus dropping the EC) the accessor value will be lost when we abandon the EC!

I'm reliably informed that there is an MVC test or two depend on the AsyncLocal flow, so I'll fix those in this PR.

@rynowak
Copy link
Member

rynowak commented May 8, 2019

This breaks our recipe for testing things that depend on localized resources in .NET.

@analogrelay
Copy link
Contributor Author

This breaks our recipe for testing things that depend on localized resources in .NET.

I'm mildly concerned that no tests seem to have failed despite this. Are there tests in this repo that should be catching this break?

As per our offline discussion, I'll capture and transfer the culture across.

{
// This will configure IHttpContextAccessor so it needs to happen INSIDE this function,
// since we are now inside the Server's ExecutionContext. If it happens out
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: Don't forget to

@analogrelay
Copy link
Contributor Author

🆙 📅 now with more culture!

/// <summary>
/// Gets or sets a value that controls if <see cref="ExecutionContext"/> and <see cref="AsyncLocal{T}"/> values are preserved from the client to the server.
/// </summary>
public bool PreserveExecutionContext { get; set; } = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: init to false ins't needed here or on line 86.

public bool AllowSynchronousIO { get; set; }

/// <summary>
/// Gets or sets a value that controls if <see cref="ExecutionContext"/> and <see cref="AsyncLocal{T}"/> values are preserved from the client to the server.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The default value is..."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ Also updating the other comment to move default value to <summary> since <remarks> don't show in IntelliSense (which is where you really want this info IMO).

@analogrelay analogrelay requested a review from rynowak May 9, 2019 18:22
@@ -59,15 +60,18 @@ internal void Configure(Action<HttpContext> configureContext)
/// Start processing the request.
/// </summary>
/// <returns></returns>
internal Task<HttpContext> SendAsync(CancellationToken cancellationToken)
internal Task<HttpContext> SendAsync(CancellationToken cancellationToken, bool preserveExecutionContext)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preserveExecutionContext should be a property like AllowSynchronousIO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. It's only used in this method and all the callers have a value they can provide here. AllowSynchronousIO is only a property because HttpContextBuilder implements IHttpBodyControlFeature and requires that the property be provided. In fact, no caller uses the setter on HttpContextBuilder, they only use the constructor argument.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And why not make it a constructor argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷‍♀️

fixes #7975

There is a 'PreserveExecutionContext' property to turn the old behavior back on. Also I had to modify where IHttpApplication.CreateContext is called since that's what sets the IHttpContextAccessor, which depends on AsyncLocals!
@analogrelay analogrelay force-pushed the anurse/7975-testserver-suppress-ec branch from 6c95f52 to 29b7a64 Compare May 9, 2019 21:42
@analogrelay
Copy link
Contributor Author

@aspnet-hello
Copy link

This comment was made automatically. If there is a problem contact [email protected].

I've triaged the above build. I've created/commented on the following issue(s)
https://github.com/aspnet/AspNetCore-Internal/issues/2481

@analogrelay analogrelay merged commit d3dc92f into master May 10, 2019
@analogrelay analogrelay added this to the 3.0.0-preview6 milestone May 10, 2019
@ghost ghost deleted the anurse/7975-testserver-suppress-ec branch May 10, 2019 03:47
@Amd3202
Copy link

Amd3202 commented May 30, 2019

I'm having the same/similar issue but i don't think it's with TestServer. I have a .netstandard 2.0 class library which I have an IHttpContextAccessor. Reading and writing to the session works fine. Then i call a SOAP service through Microsoft.VisualStudio.ConnectedService.Wcf in the class library the session gets (mostly) wiped out. Any key set before calling the webservice persists but the values are wiped out. I'm including the lib in the .netcore webapp Using 2.2 any advice would be greatly appreciated!

@analogrelay
Copy link
Contributor Author

@Amd3202 If you're having an issue or have a question I'd suggest filing a new issue and including a sample project that reproduces the issue. Otherwise it's likely we'll lose track of this thread since this is a merged PR. Open issues will show up in our triage process and we'll be able to track it better.

@Amd3202
Copy link

Amd3202 commented May 30, 2019

Thanks for the quick reply, i thought it was related... haven't opened a thread on here before i'll see if i can figure that out! Thanks.

@analogrelay
Copy link
Contributor Author

Even if it is related, it's easier for us to track in a new open issue rather than as a comment on a closed issue or merged PR :)

@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HttpContextAccessor.HttpContext is null when using TestServer and .net 2.2.2
8 participants