Repository navigation
fix(vscode-ide-companion): resolve stop() hang and fix keep-alive failure threshold (#28785) - #28789
Pranjulchaurasiya wants to merge 4 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
📊 PR Size: size/M
|
🛑 Action Required: Evaluation ApprovalSteering changes have been detected in this PR. To prevent regressions, a maintainer must approve the evaluation run before this PR can be merged. Maintainers:
Once approved, the evaluation results will be posted here automatically. |
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 two critical stability bugs in the vscode-ide-companion package: a server shutdown hang caused by active streaming connections and a resource leak in the keep-alive failure detection logic. Alongside these fixes, the PR includes a significant cleanup of the repository structure, removing various legacy configuration, documentation, and tooling files. Highlights
Ignored Files
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 the 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 counterproductive. 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. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request contains a large number of deletions across various configuration, documentation, and script files, effectively cleaning up the repository by removing obsolete build configurations, unused scripts, and outdated documentation. As there were no review comments provided, I have no specific feedback to offer.
88da634 to
1bf2555
Compare
chiruu12
left a comment
There was a problem hiding this comment.
Reporter of #28785 here. Couple of things I don't think this covers.
The keep-alive interval can still outlive stop(). keepAlive lives in the connection closure and only gets cleared in two spots, the missedPings >= 3 branch and transport.onclose. Nothing stop() can reach holds it.
So when a transport doesn't finish closing inside the 1s race, which is the exact case this is fixing, onclose never runs, this.transports gets dropped, and that timer is now unreachable. It just keeps pinging. closeAllConnections() kills the sockets but not the timer.
Storing the intervals in a Map keyed by session id next to this.transports, and clearing them in stop() before the race, would handle it.
Separate thing: pulling out missedPings = 0 turns "three in a row" into "three ever". At 60s intervals a session that stays up for a few hours will hit three transient failures eventually and get closed for it. The log line stops matching what happened too.
If the point was to stop a flapping transport from dodging the threshold, counting consecutive misses plus a total, or a failure rate over some window, gets that without dropping the reset.
d5eb3ef to
1bf2555
Compare
|
Thanks for the thorough review and both catches @chiruu12! 1. Keep-alive interval outliving 2. Added tests for both: one that simulates a hung Pushed as |
|
Second pass on this. The keepAliveIntervals map does not close the leak. It is only written inside
The tests poll with The CLA check is still red, so none of this can merge yet. One more thing, and take it however you like. The ten-strike rule came straight out of the triage bot's effort analysis at the top of the issue. That is a first pass by an automated triager, not a spec, and here it was wrong: resetting on success is exactly what a consecutive-failure counter should do. The rest of this reads the same way, right shape and wrong details, which is the usual tell. Maybe let the model do a little less of the thinking on the next one. |
…ping threshold, and robust stop() teardown (google-gemini#28785)
|
Thanks again for the sharp review Updated the PR addressing all 5 items:
All 44 tests in |
|
Hi there! Thank you for your interest in contributing to Gemini CLI. To ensure we maintain high code quality and focus on our prioritized roadmap, we only guarantee review and consideration of pull requests for issues that are explicitly labeled as 'help wanted'. This PR will be closed in 7 days if it remains without that designation. We encourage you to find and contribute to existing 'help wanted' issues in our backlog! Thank you for your understanding. |
|
Thanks for the review and feedback. I’ve addressed the requested changes, but I’m closing this PR for now rather than continuing with it. I appreciate the detailed review and guidance. |
Summary
This PR resolves two stability bugs in
vscode-ide-companion(#28785):IdeServer.stop()hangs indefinitely when active streaming MCP sessions (GET /mcp) are open.Details
IdeServer.stop()Hang:http.Server.close()waits for active connections to drain naturally. Because MCP transports maintain long-lived streaming HTTP responses, the close callback never fired.stop()now iteratesthis.transportsand calls.close()on each transport concurrently usingPromise.allSettled, bounded by aPromise.race1000ms timeout (preventing a stuck transport from blocking teardown).this.server.closeAllConnections()is invoked afterserver.close()to terminate remaining sockets, followed by an explicitthis.transports = {}best-effort cleanup.missedPingswas previously reset to0on every successful ping, allowing oscillating connections (success/fail/success/fail) to bypass the threshold of 3 missed pings indefinitely.void transport.close()whenmissedPings >= 3.@internal getTransports()getter for type-safe test access and replaced fixed sleep delays with deterministic polling in tests.Related Issues
Fixes #28785
How to Validate
cd packages/vscode-ide-companionide-server:Expected Result: All 17 tests pass, including the 4 new lifecycle tests (
a,b,c,d).Pre-Merge Checklist