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

Remove premature QuicListener.IsSupported check #44755

Closed
wants to merge 2 commits into from

Conversation

halter73
Copy link
Member

There's no reason to pay the cost of this check when HTTP/3 is not enabled. I was going to file an issue, but the fix was so simple, I just went ahead and made this PR. We can still discuss the merits here.

This means that a IMultiplexedConnectionListenerFactory always gets added to the service collection, but the upside is that we only check QuicListener.IsSupported when Kestrel actually tries to bind with QUIC which means that HTTP/3 has been opted into. Today, QuicListener.IsSupported is always checked and @eerhardt pointed out this hurts startup performance pretty significantly.

I think we should consider backporting this to 7.0.1.

@JamesNK

- There's no reason to pay the cost of this check when HTTP/3 is not enabled
@@ -36,7 +36,7 @@ internal sealed class QuicConnectionListener : IMultiplexedConnectionListener, I
{
if (!QuicListener.IsSupported)
{
throw new NotSupportedException("QUIC is not supported or enabled on this platform. See https://aka.ms/aspnet/kestrel/http3reqs for details.");
throw new NotSupportedException("QUIC and HTTP/3 are not supported or enabled on this platform. See https://aka.ms/aspnet/kestrel/http3reqs for details.");
Copy link
Member

Choose a reason for hiding this comment

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

Is there a unit test for this error? We could have a test that always runs that checks for QuicListener.IsSupported and expects an error if it is false.

@@ -20,15 +19,10 @@ public static class WebHostBuilderQuicExtensions
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder UseQuic(this IWebHostBuilder hostBuilder)
{
if (QuicListener.IsSupported)
return hostBuilder.ConfigureServices(services =>
Copy link
Member

Choose a reason for hiding this comment

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

The presence of a registered multiplexed transport factory is tested when figuring out if an endpoint supports HTTP/3. For example:

if (hasHttp3 && _multiplexedTransportFactory is null && !(hasHttp1 || hasHttp2))

Copy link
Member Author

@halter73 halter73 Oct 28, 2022

Choose a reason for hiding this comment

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

Good point. This isn't relevant if you have HTTP/3 disabled which is the .NET 7 default. Or if you have only HTTP/3 enabled which would throw either way.

But if you have HttpProtocols.Http1AndHttp2AndHttp3 configured which is the default in main, we have to pay the cost of the check regardless 😢. Do you think we could leverage your new CanBind API (#44537) for checking this in .NET 8?

If we backport this to 7 (which I still think we should do), we might just have to swallow the NotSupportedException thrown from BindAsync in the Http1AndHttp2AndHttp3 case. Fortunately, that's not the default in 7, and I don't see many people manually setting that unless they are running on a platform that supports QUIC.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should ask the S.N.Q team to look at improving QuicListener.IsSupported performance. See if it can be changed to avoid loading msquic.

Copy link
Member

@eerhardt eerhardt Oct 31, 2022

Choose a reason for hiding this comment

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

This isn't relevant if you have HTTP/3 disabled which is the .NET 7 default

dotnet/runtime#73153 enabled HTTP/3 for HttpClient by default for 7.0 rc1.

Copy link
Member

Choose a reason for hiding this comment

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

dotnet/runtime#73153 enabled HTTP/3 for HttpClient by default for 7.0 rc1.

The developer still has to opt-in by changing the request version or policy.

@build-analysis build-analysis bot mentioned this pull request Oct 27, 2022
2 tasks
…sions.cs

Co-authored-by: James Newton-King <james@newtonking.com>
@eerhardt
Copy link
Member

and @eerhardt pointed out this hurts startup performance pretty significantly.

FYI - Loading msquic was showing up in a profile when I was measuring the startup of a NativeAOT'd ASP.NET app. A NativeAOT'd app is already roughly 5-10x faster than a "regular" ASP.NET app's startup.

I wouldn't use my scenario or measurements alone as justification for changes here (especially if we are considering backporting the change). It would be good to verify how impactful this is for fully supported configurations.

@Tratcher
Copy link
Member

Tratcher commented Nov 2, 2022

dotnet/runtime#75521

Not quite what we hoped for, but better than nothing.

@ghost
Copy link

ghost commented Jan 25, 2023

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no breaking changes are introduced, please remove the pending ci rerun label to kick off a new CI run.

@ghost ghost added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jan 25, 2023
@amcasey
Copy link
Member

amcasey commented Mar 23, 2023

@halter73 suggested a comparable change in #47209, which I think subsumes this PR?

@halter73 halter73 closed this Mar 27, 2023
@halter73 halter73 deleted the halter73/check-quic-less branch March 27, 2023 21:20
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Jun 2, 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 feature-kestrel pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants