fix(encoding): flush codec after each chunk for streaming responses #4055
Closed
Rachit2323 wants to merge 3 commits intoactix:mainfrom
Closed
fix(encoding): flush codec after each chunk for streaming responses #4055Rachit2323 wants to merge 3 commits intoactix:mainfrom
Rachit2323 wants to merge 3 commits intoactix:mainfrom
Conversation
…ithout an explicit flush, gzip/deflate/zstd buffers all chunks and releases them only at stream EOF, causing middleware::Compress to delay all output until the response stream ends. Fixes actix#3410
Member
|
Please do not paste AI output directly, we don't welcome slops. |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Fixes #3410
Problem
When using
middleware::Compresswith a streaming response, chunks don'tarrive at the client progressively — instead everything is buffered and
delivered all at once when the stream ends.
For example, a response that sends one chunk immediately and another after
5 seconds will show nothing for 5 seconds, then both chunks appear at the
same time.
Why it happens
The gzip/deflate/zstd codecs buffer incoming data internally waiting for
more bytes to compress efficiently.
write()feeds data in but the codecdecides when to emit output. Without an explicit flush, it holds everything
until
finish()is called at stream EOF.Fix
Added
ContentEncoder::flush()which calls sync flush on the underlyingcodec, and call it after every
write()inpoll_next. This forces thecodec to release each chunk immediately rather than waiting for the stream
to end.
Small trade-off: slightly lower compression ratio per chunk, but this is
the same behaviour as nginx/Apache and the right call for streaming.