Conversation
|
|
Confidence Score: 5/5Safe to merge — the fix correctly mirrors the deferred-completion pattern already proven in inference.go, and the defer ordering (runCompleter → cancel → reader.Done → traceCompleter) ensures post-hooks and spans are always finalised cleanly. All three concerns raised in the previous review round (leaked trace span, magic number heartbeat constant, cancel-before-completer ordering) are fully addressed. The goroutine's cleanup sequence now matches inference.go. The 100ms atomic poll for the completer slot is a bounded busy-wait; in the absence of a TransportInterceptorMiddleware the slot stays nil and the wait fires on every disconnect, but this is a cosmetic latency concern rather than a correctness problem. No race conditions were found: completerSlot escapes to the heap, traceCompleter is captured before goroutine launch (tracing middleware sets it before calling next(ctx)), and ctx is not accessed inside the goroutine. No files require special attention. Important Files Changed
Reviews (8): Last reviewed commit: "fix: mcp sse hang fixes" | Re-trigger Greptile |
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughSignals streaming context, exposes an atomic transport post-hook completer slot, defers trace completion, sets ChangesSSE Streaming Robustness & Tracing Coordination
Sequence Diagram(s)sequenceDiagram
participant Client
participant SSEHandler as Bifrost HTTP handler
participant TransportPostHook as Transport Post-hook (atomic.Value)
participant TraceCompleter as Trace completer (ctx.UserValue)
Client->>SSEHandler: Open SSE connection
SSEHandler->>Client: Send "connection/opened" SSE frame
alt send fails
SSEHandler-->>Client: Abort streaming / exit
else send succeeds
loop every 15s
SSEHandler->>Client: ": ping" SSE comment heartbeat
end
alt client disconnect or bifrostCtx.Done
SSEHandler->>TransportPostHook: wait ~100ms for completer
TransportPostHook-->>SSEHandler: provide completer/logs (if set)
SSEHandler->>TraceCompleter: invoke with collected logs
SSEHandler-->>Client: cleanup (cancel, reader.Done)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@transports/bifrost-http/handlers/mcpserver.go`:
- Around line 150-155: The SSE handler sets
BifrostContextKeyDeferTraceCompletion but does not seed the deferred post-hook
completer, so middlewares.go skips snapshot/completion and pooled objects leak;
before returning the stream in the handler in mcpserver.go, create and
SetUserValue for BifrostContextKeyTransportPostHookCompleter with the same
completer type used by other streaming handlers, and ensure the stream teardown
path drains/invokes that completer (mirror the logic used in the other streaming
handlers) so the deferred transport/tracing path runs and pooled objects are
released.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: eab98ee8-e58b-4652-981f-71a6cf38d843
📒 Files selected for processing (1)
transports/bifrost-http/handlers/mcpserver.go
09c4f02 to
bc19ce7
Compare
08b9a17 to
0132257
Compare
0132257 to
e3d6e25
Compare
c092d13 to
e34323a
Compare
e3d6e25 to
3dcc042
Compare
3dcc042 to
e2bc0b5
Compare
e34323a to
553a797
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
transports/bifrost-http/handlers/mcpserver.go (1)
71-75:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDuplicate tool filter registration.
The same
WithToolFiltercall is registered twice onglobalMCPServerwith identical comments. This appears to be an accidental duplication that could cause the filter to run twice per request.🔧 Proposed fix
// Register per-request tool filter so x-bf-mcp-include-clients and x-bf-mcp-include-tools are respected on tools/list server.WithToolFilter(handler.makeIncludeClientsFilter())(handler.globalMCPServer) - - // Register per-request tool filter so x-bf-mcp-include-clients and x-bf-mcp-include-tools are respected on tools/list - server.WithToolFilter(handler.makeIncludeClientsFilter())(handler.globalMCPServer)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@transports/bifrost-http/handlers/mcpserver.go` around lines 71 - 75, The WithToolFilter registration for handler.makeIncludeClientsFilter() is duplicated on handler.globalMCPServer; remove the redundant call so the filter is only registered once (keep a single server.WithToolFilter(handler.makeIncludeClientsFilter())(handler.globalMCPServer) and delete the duplicate) to prevent the filter executing twice per request.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@transports/bifrost-http/handlers/mcpserver.go`:
- Around line 71-75: The WithToolFilter registration for
handler.makeIncludeClientsFilter() is duplicated on handler.globalMCPServer;
remove the redundant call so the filter is only registered once (keep a single
server.WithToolFilter(handler.makeIncludeClientsFilter())(handler.globalMCPServer)
and delete the duplicate) to prevent the filter executing twice per request.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 21380091-38fb-49a8-b202-2559e1566838
📒 Files selected for processing (1)
transports/bifrost-http/handlers/mcpserver.go
e2bc0b5 to
83ff8a4
Compare
553a797 to
825ea3b
Compare
Merge activity
|

Summary
Fixes a deadlock and connection reliability issue in the MCP server's SSE handler. Without this fix, post-hook middleware (transport-plugin and tracing) would attempt to materialize the SSE response body during cleanup, blocking indefinitely waiting for an EOF that never arrives while the streaming goroutine is still running. Additionally, idle SSE connections had no heartbeat mechanism, making it impossible to detect client disconnects since fasthttp never cancels the bifrost context on its own.
Changes
BifrostContextKeyDeferTraceCompletionon the request context before streaming begins, signaling to transport-plugin and tracing middlewares to skip eager body materialization that would deadlock on the open SSE stream.X-Accel-Buffering: noresponse header to prevent nginx and similar reverse proxies from buffering SSE events.<-(*bifrostCtx).Done()wait with a 15-second ticker that sends SSE comment heartbeats (: ping\n\n). This keeps idle connections alive through proxies and detects client disconnects viareader.Send()returningfalse.reader.Send()return check so a disconnected client causes an early exit rather than continuing the goroutine.Type of change
Affected areas
How to test
Connect an SSE client to the MCP server endpoint and verify:
go test ./...Breaking changes
Related issues
Security considerations
None.
Checklist
docs/contributing/README.mdand followed the guidelines