YARP should support gracefully closing WebSocket connections to the backend during shutdown
- Dominant language
- C#
- Stars
- 9.6k
- Forks
- 933
- Avg merge
- 12d 18h
- Merged PRs (30d)
- 2
Description
### What should we add or change to make your life better?
When YARP shuts down while proxying a WebSocket to the backend, the backend has no way to observer that the proxy wants to gracefully close the connection. This means that YARP will always hit the Host's ShutdownTimeout which was recently [increased to 30 seconds](https://github.com/dotnet/runtime/pull/63712) before exiting. Because `HttpForwarder` proxies WebSockets using `IHttpUpgradeFeature` rather than `IHttpWebSocketFeature`, it has no mechanism to notify the backend that it wants to try gracefully closing the connection. If it used the WebSocket feature instead, it could initiate a [WebSocket closing handshake](https://datatracker.ietf.org/doc/html/rfc6455#section-1.4) which should speed up YARP shutdown and restarts dramatically in this situation.
Parsing and redoing the WebSocket framing will have some minor performance implications and injecting a close handshake into a proxied WebSocket could be behavior people don't want, so this should probably be made opt-in. Although, I do think the fast majority of customers would prefer this behavior.
Related: I filed https://github.com/dotnet/aspnetcore/issues/42057 so Kestrel exposes HTTP/2 and HTTP/3 GOAWAY frames to apps on the back which should also help the proxy close long running HTTP/2 and HTTP/3 requests to Kestrel backends. This is a little safer though because YARP can continue sending data to the backend after sending a GOAWAY. This is not possible after starting the WebSocket closing handshake.
Contributor guide
Research direction
Start by reading the WebSocket proxying path that uses IHttpUpgradeFeature and compare it with IHttpWebSocketFeature. Review the linked RFC 6455 closing-handshake behavior and the opt-in and performance concerns in the issue. Done means backend WebSocket connections can be gracefully closed during YARP shutdown without breaking existing proxy behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100