fix: propagate client disconnects to response body streams#93906
Open
coffeeispower wants to merge 2 commits into
Open
fix: propagate client disconnects to response body streams#93906coffeeispower wants to merge 2 commits into
coffeeispower wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Fixes response stream cancellation when the client disconnects before the response body finishes streaming.
Why?
Long-lived streaming responses need their body stream to be cancelled when the client connection is closed. Without that cancellation, application cleanup logic attached to the stream may not run, which can leave per-client resources alive after the client has gone away even if the app has registered a event listener using
request.signal.addEventListener("abort", ...)This was found while building Radiant, a TypeScript web app for creating radios that you can schedule playlists, songs, ad sections and other things and it serves long-lived ICY/audio streams from Next.js route handlers. Each listener connection owns stream resources and registers cleanup logic that must run when the client disconnects.
In the real reproduction case, connecting with
mpvand then closing the player aborted the HTTP response, but the response body stream was not cancelled. The route returned, but the stream finalizer responsible for removing the listener from the radio runtime did not run until this piping path was patched to propagate the disconnect to the body stream.This is not only specific to audio: the same issue can affect any long-lived response body stream that relies on cancellation/finalizers for cleanup, such as event streams, proxy streams, or custom streaming route handlers.
How?
The response piping path now propagates client aborts to the response body stream. It also avoids surfacing noisy double-close errors when the writable side has already been closed or errored during disconnect cleanup.