fix(sse): support streaming responses on Fiber/fasthttp adapters#1059
Merged
Conversation
SSE (and other streaming responses) failed on the Fiber adapters with "unable to flush", because Fiber is built on fasthttp, whose RequestCtx does not implement http.Flusher and can't flush the response body synchronously from within the handler; it only streams via SetBodyStreamWriter. Add an internal, unexported streaming hook: the sse package detects an optional bodyStreamer interface on the context (alongside the existing unwrapper/writeDeadliner) and, when present, streams through the adapter's callback. The Fiber v2 and v3 adapters implement it via fasthttp's SetBodyStreamWriter, passing a small writer that satisfies io.Writer, http.Flusher, and the write-deadline interface so the shared send loop treats it uniformly. fasthttp stays an indirect dependency and is not imported by the sse package or the humafiber source. The SSE send loop is extracted into a shared stream() function reused by both the direct-write and streaming paths. Fixes #888.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1059 +/- ##
=======================================
Coverage 93.12% 93.13%
=======================================
Files 23 23
Lines 4932 4938 +6
=======================================
+ Hits 4593 4599 +6
Misses 275 275
Partials 64 64 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Add a white-box test that drives Register through a fake huma.Adapter whose context implements bodyStreamer, exercising the Fiber/fasthttp streaming branch (which codecov can't credit from the adapter tests, since adapters are excluded and coverage is measured per package).
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.
Fixes #888.
Server-Sent Events (and other streaming responses) fail on the Fiber adapters with
unable to flush. Fiber is the only adapter built on fasthttp rather thannet/http, andfasthttp.RequestCtxdoesn't implementhttp.Flusher— it can't flush the response body synchronously from within the handler, only via the deferredSetBodyStreamWritercallback. Every other adapter (chi, echo, gin, go, httprouter, mux, bunrouter, flow) exposes anhttp.Flusherand already works.Approach
An internal, unexported streaming hook — no new public API:
ssepackage detects an optionalbodyStreamerinterface on the context, alongside the existingunwrapper/writeDeadlinercapability interfaces. When present, it streams through the adapter's callback; otherwise it writes toBodyWriterdirectly as before.SetBodyStreamWriter, passing a small writer that satisfiesio.Writer,http.Flusher, and the write-deadline interface, so the shared send loop treats it uniformly.fasthttpstays an indirect dependency — it is not imported by thessepackage or thehumafibersource, so no SSE user (chi/net-http/etc.) picks up a new direct dependency.stream()function reused by both paths.Tests
humafiber.TestSSE(v3) andTestSSEV2(v2) drive SSE end-to-end through the real fasthttp stream path and assert the exact streamed output.Credit
Thanks to @zhouyusd for surfacing this and the first attempt in #1014, and to the reporters on #888. This PR takes a different approach that keeps
fasthttpout of the core dependency graph, so it supersedes #1014.