lymerin opened a new pull request, #7730: URL: https://github.com/apache/shenyu/pull/7730
Fixes #7708 ### Problem - `AiStatisticServerHttpResponse.writeAndFlushWith()` processes every inner publisher independently through `appendResponse()`. - `appendResponse()` previously created a new `BodyWriter` and, for gzip responses, a new `GzipStreamDecoder` for each inner publisher. - The production streaming path uses `body.map(Flux::just)`, so network buffers become separate inner publishers. When an SSE usage event or gzip stream spans those buffers, the fallback tail and gzip decoding state cannot survive across inner publishers. ### Impact - A valid SSE usage event split across streaming flush boundaries can lose its reported `completion_tokens`. - The response bytes are still forwarded correctly to the client, but the token limiter may record `0` instead of the actual usage. - This makes token-window accounting inaccurate for affected streaming AI responses. - Gzip decoding state can be affected by the same inner-publisher lifecycle when compressed data spans multiple buffers. ### Changes - Create the writer and optional gzip decoder once per response write subscription, sharing them across all inner publishers in `writeAndFlushWith()` and using the same lifecycle structure in `writeWith()`. - Keep one `GzipStreamDecoder` for the whole response so gzip header and inflater state survive buffer and flush boundaries. - Reuse the same writer and decoder while processing every inner publisher in `writeAndFlushWith()`. - Finalize decoder cleanup and fallback token extraction once when the whole response terminates instead of once per inner publisher. - Preserve the existing streaming flush behavior and forwarded response bytes. - Keep fallback retention bounded by the existing `BodyWriter` limit. - Add focused regression tests for fragmented usage fields and values, gzip responses, unchanged forwarded bytes, and finalization after the outer publisher completes. ### Validation - All 22 token-limiter module tests passed. - Checkstyle passed with no violations. - Apache RAT passed with no unapproved licenses. ### Checklist Make sure that: - [x] You have read the [[contribution guidelines](https://shenyu.apache.org/community/contributor-guide)](https://shenyu.apache.org/community/contributor-guide). - [x] You submit test cases (unit or integration tests) that back your changes. - [x] Your local test passed `./mvnw clean install -Dmaven.javadoc.skip=true`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
