fix: Terminate connection on closing the stream from the DirectDruidClient#19607
fix: Terminate connection on closing the stream from the DirectDruidClient#19607LakshSingla wants to merge 3 commits into
Conversation
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 2 |
| P3 | 0 |
| Total | 2 |
Reviewed 7 of 7 changed files.
This is an automated review by Codex GPT-5.5
| { | ||
| final TrafficCop trafficCop; | ||
| synchronized (done) { | ||
| if (done.get()) { |
There was a problem hiding this comment.
[P2] Early close still needs to discard completed buffered response
When the server has already finished sending the response, done is true, so this new close() override returns before setting discard, clearing queue, or delegating to SequenceInputStream.close(). A caller that stops after the first rows while a fast historical has already filled the remaining queue will now retain all queued InputStreamHolder/ChannelBuffer chunks until the yielder and parser are GC'd; before this change, SequenceInputStream.close() drained and removed the queued elements once done was true. The close path should still clear/discard queued buffers for done == true; only the connection abort needs to be skipped once the response is complete.
| * Intended for callers that decide they no longer need the rest of the response (for example, because the | ||
| * consumer of the resulting stream has been closed early) | ||
| */ | ||
| void abort(); |
There was a problem hiding this comment.
[P2] Keep TrafficCop source and binary compatible
Adding abort() as a second abstract method makes TrafficCop no longer a functional interface and forces every out-of-tree mock or custom HttpClient implementation to add the method, with existing compiled implementations at risk of AbstractMethodError if this hook is invoked. Since only the Netty implementation needs special behavior, make abort() a default no-op and let Netty override it; that preserves existing lambda/test implementations while still enabling this PR's connection-abort path.
There was a problem hiding this comment.
I don't want to add a default no-op for this modification. The callers must explicitly define what close() should do.
There was a problem hiding this comment.
Thanks for clarifying. I agree Netty should define the actual close behavior explicitly, and it does here. My concern is narrower: TrafficCop is a public nested interface that was previously SAM-compatible, so adding abort() as a required abstract method breaks source compatibility for lambdas/custom HttpClient fakes and can still throw AbstractMethodError for compiled implementations if this path is called. A default no-op does not stop Netty from overriding abort(); it just preserves the existing contract for implementations that cannot abort. If the intent is to require all implementations to make an explicit choice, I think this should be treated as an intentional API break and reflected accordingly. Reviewed 7 of 7 changed files.
DirectDruidClientreturns aSequenceInputStreamconsisting of the chunks fetched by the downstream data servers.close()on theSequenceInputStreamconsumes the entire iteration, attempts to call close on the elements, before returning to the caller. This means that on attempting toclose()the input stream returned by the DirectDruidClient, we end up fetching the entire response from the data servers. This fetching is wasteful, as we discard the results, and there's nothing to be done on the remaining chunks.This PR short-circuits the close() on the stream returned by the DirectDruidClient, so that close() exits immediately, and terminates the connection between the broker and the dataservers.