Close connections as quickly and gracefully as possible on shutdown#623
Conversation
e10dceb to
88fe39a
Compare
| AbortAwaiting(); | ||
|
|
||
| // Return all blocks | ||
| var block = _head; |
There was a problem hiding this comment.
This is only called after the socket is closed so there should not be any more incoming data. The AbortAwaiting call kills any consumers. (If all else fails, the finalizer still returns the block in production, but it would crash the process in debug builds)
|
Does this provide a deterministic disposal point for the connection? (rather than any finalization) |
|
Wanted to do a pooled SocketOutput - but bit complicated atm |
| } | ||
|
|
||
| public void Stop(TimeSpan timeout) | ||
| { |
There was a problem hiding this comment.
Add
#if !DEBUG
if (_thread != null)
{
_thread.IsBackground = true;
}
#end- Make the time given for requests to complete gracefully configurable. - Complete all async reads so calling code can re-check whether to stop request processing and exit if in between requests. - Don't wait for a FIN from the client since some browsers (e.g. IE & Chrome) will take a long time to send one. - Ensure all ConnectionFilters complete before the memory pool is disposed. - Ensure blocks get returned even when a ConnectionFilter produces a failed read
- Even when safe handles are disposed explicitly, ReleaseHandle is sometimes called on another thread which breaks uv_close. - Ensure we close the UvAsyncHandle the uv loop so that the second call to uv_run always completes without a timeout/Thread.Abort. - Re-enable some tests. Add skip conditions for those that aren't passing.
- This means connections become untracked sooner than before and not all blocks will necessarily be returned. - The assertion in the MemoryPoolBlock2 finalizer was weakened because FilteredStreamAdapter will continue to use blocks after libuv stops tracking the associated connection. - Make 100% sure we don't accept new connections after we dispose the listen socket by using a flag. - Add a (currently unused) AllowStop method to KestrelThread. This is meant to be called from listeners when we stop accepting new connections, but needs investigation to prevent flakiness.
- Maybe things are better now with graceful shutdown *crosses fingers*
|
@benaadams the "deterministic disposal point for the connection" would be I don't think there is a need for it currently, but if you want |
Properly return pooled blocks in SocketInput #580 Kestrel takes 2-3 seconds to shutdown if any connections have been made #247