fix(cli): release disconnected event streams#11646
Merged
Merged
Conversation
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (4 files)
Reviewed by gpt-5.4-20260305 · Input: 119.4K · Output: 10.1K · Cached: 408.5K Review guidance: REVIEW.md from base branch |
chrarnoldus
approved these changes
Jun 29, 2026
vkeerthivikram
pushed a commit
to vkeerthivikram/kilocode
that referenced
this pull request
Jun 30, 2026
fix(cli): release disconnected event streams
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.
Global SSE streams can survive client disconnects and reconnects under the current Effect Node HTTP stack. Each stale stream remains subscribed to
GlobalBuswith an unbounded callback queue. Becausesession.diffevents can include complete multi-megabyte patches, repeated reconnects can retain tens of gigabytes of diff payloads.Live heap snapshots from the leaking process showed the retained memory was dominated by duplicated Git patch strings, not native heap growth or database handles. At 31.1 GB physical footprint, the JavaScript heap was 15.78 GB, with 15.21 GB held by strings. The largest retained groups were repeated
diff --gitpayloads from generated.windows-spike/zig-pkg/...files: the top Git patch string groups alone accounted for 10.89 GB. A previous 24 GB capture showed the same retainer path, then the later capture grew by another 4.07 GB of string storage as additional stale global event listeners and queued diff events accumulated.The retained path was:
The later heap contained 27 live
GlobalBuslistener closures for global SSE streams, while logs showed 29 global event connections and only 2 disconnections. Each orphaned listener held an unbounded queue. One representative queue contained more than 3,100 undelivered global events.Observe the underlying Web request abort signal or Node request/socket close event and explicitly interrupt the SSE stream. Closing the stream scope runs its
acquireReleasefinalizer, unregisters theGlobalBuslistener, and releases the queue immediately instead of depending on transport cancellation propagation. This removes the identified retention source: stale global SSE queues can no longer keep full diff payloads alive after clients disconnect.Add a real Node HTTP server regression that repeatedly connects and disconnects global event clients and requires the listener count to return to its baseline after every disconnect. This restores the dead-stream cleanup guarantee previously addressed by #8952 for the current Effect-based route implementation.