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

rework HTTP version handling #51454

Merged
merged 3 commits into from
Apr 27, 2021
Merged

Conversation

geoffkizer
Copy link
Contributor

Rework and try to simplify some of the HTTP version handling in HttpConnectionPool.cs.

This is preparation for request queuing changes I'm working on.

@ghost
Copy link

ghost commented Apr 18, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Rework and try to simplify some of the HTTP version handling in HttpConnectionPool.cs.

This is preparation for request queuing changes I'm working on.

Author: geoffkizer
Assignees: -
Labels:

area-System.Net.Http

Milestone: -

@geoffkizer
Copy link
Contributor Author

/azp run runtime-libraries-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@davidfowl
Copy link
Member

Did this add more state machines on the common path?

@geoffkizer
Copy link
Contributor Author

Did this add more state machines on the common path?

Possibly, yeah. I tried to avoid state machines where possible.

That said, this is an intermediate step in bigger changes, and I don't think it makes sense to micro-optimize state machine allocation until we know where the code is going to end up.

That of course is the problem with state machine optimizations; they are fragile and often break with any sort of refactoring. They are fundamentally at odds with good code hygiene. Which is unfortunate.

That said, all this will be fixed with state machine caching, right? :)

return await ConstructHttp11ConnectionAsync(async, socket, stream!, transportContext, request, cancellationToken).ConfigureAwait(false);
}
HttpConnection http11Connection = await ConstructHttp11ConnectionAsync(async, socket, stream!, transportContext, request, cancellationToken).ConfigureAwait(false);
ReturnConnection(http11Connection);
Copy link
Member

Choose a reason for hiding this comment

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

So we create H/11 connection and immediately return it to the pool. So if I get it right, under certain circumstances, another request can take this connection in the meantime and the currently processed request will get queued instead? And that's what we want, or not, or we do not care?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's possible.

It's a weird scenario because you would have to be issuing both HTTP/1.1 and HTTP/2 requests against the same server (otherwise you wouldn't have any existing HTTP/1.1 requests queued). So I'm not sure we can that much...

But if you do that, and you do have HTTP/1.1 requests queued already, I'd argue that those queued requests should be serviced first. That's what will happen for any other HTTP2 requests that are implicitly queued by the HTTP2 connection creation semaphore. So I'd argue this behavior is both better and more consistent than existing behavior.

Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

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

LGTM, thanks.
We could probably get rid of net_http_requested_version_cannot_establish resource string. I think that with this change it's not used anymore.

@geoffkizer
Copy link
Contributor Author

Actually I didn't notice that net_http_requested_version_cannot_establish and net_http_requested_version_not_enabled are in fact different errors... Should I restore the code that throws the former? Not sure what the intended difference is here.

@ManickaP
Copy link
Member

I think that having just one message is perfectly sufficient here.

The original thinking was to distinguish between:

  • h2c/h3 being disabled, for instance via the AppSwitches we have -- something the user can influence
  • not being able to create the connection for the requested version, for instance ALPN returning only HTTP/1.1 -- something the user cannot influence

But I think it's needlessly detailed. If someone wants to dig into the exact reason, the call stack will tell.

@geoffkizer
Copy link
Contributor Author

Makes sense, thanks. That said, I suspect the message we want here is net_http_requested_version_cannot_establish, does that seem right?

@ManickaP
Copy link
Member

Yes, seems better.

@geoffkizer
Copy link
Contributor Author

/azp run runtime-libraries-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@geoffkizer geoffkizer merged commit 08e00be into dotnet:main Apr 27, 2021
@geoffkizer geoffkizer deleted the versionhandlingrework branch April 27, 2021 01:50
@ManickaP ManickaP mentioned this pull request May 5, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants