Repository navigation
fix(mcp): exit promptly on stdin EOF while a tool call is in flight - #125
Conversation
…116) Abandon the tokio runtime with shutdown_background instead of dropping it, so a worker blocked in a synchronous index build is not joined after the client disconnects.
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 8 |
| Duplication | 4 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Code Review
This pull request introduces a block_then_abandon helper function in mcp_server.rs to run a future to completion and then immediately shut down the Tokio runtime in the background without waiting for worker threads to join, preventing the process from hanging on stdin EOF. It also adds a corresponding unit test. The review feedback suggests wrapping the runtime in a custom drop guard within block_then_abandon to ensure shutdown_background is called even if the future panics, preventing a potential hang during panic unwinding.
There was a problem hiding this comment.
cubic analysis
No issues found across 1 file
Linked issue analysis
Linked issue: pleaseai/code-search#116: parity(#282): csp mcp should exit promptly on stdin EOF while an index build is in flight
| Status | Acceptance criteria | Notes |
|---|---|---|
| Exit promptly after stdin EOF during an in-flight build | The helper abandons blocked workers, but the E2E run took about six seconds and no integration test asserts the one-second target. |
Architecture diagram
sequenceDiagram
participant Client as MCP Client (stdin)
participant RMCP as rmcp Server
participant Handler as Tool Handler
participant Worker as Tokio Worker
participant Runtime as Tokio Runtime
participant Helper as block_then_abandon
Note over Client,Runtime: MCP Server Lifecycle with fix
Client->>RMCP: stdin data (initialize, search tool call)
RMCP->>Handler: dispatch search / find_related
Note over Handler,Worker: Tool call blocks worker synchronously
Handler->>Worker: index build / model inference
Client->>RMCP: CHANGED: stdin EOF detected
RMCP->>RMCP: Initiate shutdown (QuitReason::Closed)
Note over RMCP,Runtime: Up to 5s drain of in-flight handler responses
RMCP->>Helper: waiting() returns
Helper->>Runtime: CHANGED: shutdown_background() (abandon worker)
alt Worker still running (index build in flight)
Runtime->>Runtime: CHANGED: Abandon worker (no join)
Runtime-->>Helper: process exits immediately (~0s)
else Worker already finished
Runtime->>Runtime: Normal shutdown
Runtime-->>Helper: process exits
end
Note over Client,Helper: Old behavior: drop(runtime) joined worker,<br/>waited up to 90s for index build
Note over Helper,Worker: Known trade-off: in-flight index save /<br/>git clone may be cut off on exit
|
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new helper function block_then_abandon in mcp_server.rs to drive a future to completion on a Tokio runtime and then abandon the runtime without joining its workers. This prevents the csp mcp process from hanging on stdin EOF if there are active synchronous tasks running on runtime workers. The change includes a custom Drop guard to handle both normal execution and panics, along with corresponding unit tests to verify the behavior. There are no review comments, so no feedback is provided.
|



Summary
After stdin EOF,
csp mcpstayed alive until a tool call that was mid index-build finished. Thesearch/find_relatedhandlers run synchronous index/model code inline on a tokio worker, and dropping theRuntimeat the end ofrun_mcpjoins that worker.run_mcpnow goes throughblock_then_abandon, which callsRuntime::shutdown_background()instead of dropping the runtime, so the process exits as soon aswaiting()returns. Mirrors upstream semble MinishLab/semble#282.Remaining bound: rmcp 1.7 drains in-flight handler responses for up to 5 s on
QuitReason::Closedbeforewaiting()returns. That is internal to rmcp and left as is.Known trade-off of abandoning workers: an in-flight index save or git clone is cut off when the process exits, as with any SIGKILL-style exit. Not addressed here.
Test:
block_then_abandon_does_not_join_a_blocked_workerparks a worker in a 30 s sleep (synchronised via a oneshot) and asserts the helper returns in under 5 s. Withdrop(rt)it fails after 30 s; with the fix it passes in about 0 s.E2E (debug build, about 4000-file / 120k-line scratch tree, scratch HOME with no index cache, HF model cache warmed beforehand;
initialize,searchtool call, stdin closed after 1 s):Related issue
Closes #116
Checklist
cargo test --workspace: 340 + 28 passed)cargo fmt,cargo clippy -D warnings)BREAKING CHANGE:note is includedSummary by cubic
Fixes
csp mcphanging after stdin EOF when a tool call's index build is still in flight. The process now abandons the tokio runtime withshutdown_backgroundinstead of dropping it, so it exits without joining the blocked worker. Closes #116.Written for commit 364c2d2. Summary will update on new commits.