-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
[Kestrel] Move to GenericHost #24279
Conversation
I'm having a difficult time fixing the tests, I think the reason is the different implementation of |
Yes, it's different because StopAsync was added to the host later. The tests should call StopAsync. |
I still couldn't pass aspnetcore/src/Servers/Kestrel/Core/src/Internal/Infrastructure/TransportConnectionManager.cs Line 88 in 49aecc3
|
Looks like a few tests are still failing because StopAsync isn't being called. |
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.
I'm not sure about the other test failure. Might have to take a closer look in a bit.
@@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests | |||
/// </summary> | |||
internal class TestServer : IDisposable, IStartup |
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.
We should make TestServer implement IAsyncDisposable, so we can just change our using
s to await using
s. Even though IHost doesn't implement IAsyncDisposable, Host does so we can just cast.
Surprisingly, it doesn't look like disposing the Host actually stops it when it's running, but I haven't tested that. Not a big deal either way as we can always call Host.StopAsync() before calling Host.DispooseAsync() in TestServer.DisposeAsync().
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.
Should I add Host.StopAsync()
in TestServer.DisposeAsync()
? Right now I call server.StopAsync()
for every instance of TestServer
before it is disposing.
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.
That's what we did in SignalR tests. It would clean up all the tests a little :D
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.
Ok. Time to revert some commits 😁 I'll remove the server.StopAsync
from the tests.
}) | ||
.UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName) | ||
.UseSetting(WebHostDefaults.ShutdownTimeoutKey, TestConstants.DefaultTimeout.TotalSeconds.ToString()) | ||
.Build(); | ||
|
||
_host.Start(); |
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.
It doesn't have to be done for this PR, but long term I'd like to get rid of all calls to the IHost.Start() and IHost.Dispose() in our tests and instead use their async alternatives. This will mean moving away from using the TestServer constructor to give as an already-started TestServer. We might need to switch to an async TestServer factory method instead.
Took a look at the ServerShutsDownGracefullyWhenMaxRequestBufferSizeExceeded test. It looks like close is working the same as before, where the server shutdown is closing ungracefully because of the blocking app code, the only difference between WebHost and Host is that after the server shutdown there is a cancellation token check in Host which is causing the exception, in WebHost this check didn't exist.
The test name seems to indicate there should be a graceful close, so either the test name isn't quite accurate, or the server code has changed since this test was made and there isn't really a check for graceful close in this test. @Tratcher @halter73 Thoughts on this test? Should we just put a |
src/Servers/Kestrel/shared/test/TransportTestHelpers/TestServer.cs
Outdated
Show resolved
Hide resolved
Regarding ServerShutsDownGracefullyWhenMaxRequestBufferSizeExceeded. It's too bad we're just now noticing the difference in behavior for ungraceful shutdown with the generic Host. Kestrel has always tried to treat the token being canceled during KesterlServer.StopAync() as gracefully as possible, since long running requests/connection that aren't listening to the stopping notification are not that uncommon. Kestrel writes a debug log, but that's it. It doesn't throw which would cause most apps to exit with an exception. I think we might need to fix the runtime to just remove the call to |
Basically the semantics when passing a canceled token (or a token that becomes canceled) to KestrelServer.StopAsync has always been to do an abortive shutdown without throwing, but then generic host is treating a canceled token as indicating StopAsync can be completely skipped (at least for the IHostedLifetime) and StopAsync should throw. Generic host might be using the more common semantics for CancellationToken, but we need to be using Kestrel's semantics if we're going to use the CancellationToken to indicate shutdown should become abortive (rather than to indicate shutdown should be skipped) and I don't see any alternative this late before 5.0. |
@halter73 lets talk after triage. People have been using Kestrel this way since 3.0, we shouldn't be changing the host's behavior now. |
Hello @BrennanConroy! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
Part of #20964