fix(orchestrator): preserve completed responses on client disconnect#1059
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical edge case in the orchestrator's outbound streaming logic where client disconnections near the completion of a stream could lead to incorrectly marking a fully completed response as 'canceled' or 'failed'. The changes introduce a more robust finalization mechanism that aggregates partial stream data to determine the true completion status, ensuring that valid responses are always persisted correctly, regardless of client-side timing issues. This improves the reliability of stream processing, particularly in complex multi-hop proxy environments. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request addresses an important edge case in stream handling where a completed stream could be incorrectly marked as canceled if the client disconnects near completion. The fix introduces logic to aggregate response chunks and determine completion status from the aggregated payload, even without a terminal stream event. The changes are well-tested with new integration and unit tests. My review focuses on a couple of areas for simplification and improved maintainability in the new logic.
|
应该可以做的通用一点,不需要针对 response 特殊处理。 agg 以后,如果 usage 有数据,应该就是完整的了 |
|
Updated this based on your suggestion. The completion check is now generic instead of special-casing Responses:
So I also cleaned up the earlier review leftovers around the removed status-based path and kept the regression coverage for the client-disconnect case. |
5c88768 to
f913e45
Compare
f913e45 to
fed294c
Compare
What this fixes
When the client disconnects near the end of a streamed response, AxonHub may observe
ctxcancellation before the local stream consumer sees the terminal event.In the
Claude Code -> AxonHub -> Codexchain, that can misclassify an actually completed response as canceled / failed even though the full response has already been streamed upstream.Approach
This update keeps the completion proof generic instead of special-casing OpenAI Responses status values.
The outbound finalization logic now treats a response as completed when either:
meta.Usage != nilAt the same time:
ctxcancellation alone is no longer treated as automatic failure if completion has already been provenWhy this shape
The maintainer feedback was to avoid protocol-specific completion handling in the orchestrator.
Using aggregated usage as an additional positive completion signal makes the rule work across providers / formats that already populate usage on complete responses, while still preserving terminal-event-based completion for streams that do not rely on usage.
Tests
This PR includes:
internal/server/orchestrator/outbound_test.gointegration_test/openai/responses/streaming/client_disconnect_test.goCovered cases include:
Verification
go test ./internal/server/orchestrator/...