Skip to content

fix: handle SSE stream disconnections #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mrene
Copy link
Contributor

@mrene mrene commented Mar 28, 2025

If the HTTP SSE stream gets disconnected, future calls will fail due to a missing transport for response messages. This adds a Connected() bool method to verify the connection status, and adds a predefined error indicating that the connection was interrupted.

Summary by CodeRabbit

  • New Features
    • Introduced reliable connection tracking so users can now verify the active state of the streaming client.
    • Provided clearer error notifications for connection issues, ensuring improved feedback when connectivity is disrupted.

…eam is active before a new request can be sent
Copy link
Contributor

coderabbitai bot commented Mar 28, 2025

Walkthrough

The update enhances the SSE client by introducing a new boolean field connected within the SSEMCPClient struct using atomic operations for thread-safe access. New error variables (ErrDisconnected, ErrNotInitialized, and ErrEndpointNotReceived) replace inline error messages, improving error granularity. The connection status is now explicitly managed: the Start method marks the client as connected upon a successful connection, while the readSSE method resets this status when reading ends. Additionally, a new method Connected allows external retrieval of the current connection state.

Changes

File Change Summary
client/sse.go - Added connected field to SSEMCPClient using atomic.Bool for thread-safe connection management.
- Introduced error variables: ErrDisconnected, ErrNotInitialized, and ErrEndpointNotReceived to replace inline error messages.
- Updated Start and readSSE to set/reset the connection status.
- Added Connected method to expose the connection state.
- Modified sendRequest to check the connection status and return ErrDisconnected if not connected.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
client/sse.go (2)

132-134: Good addition of the Connected() method.

The new Connected() method provides a clean way for client code to check the connection status before attempting operations that require an active connection.

Consider adding documentation comments for this method to match the style of other methods in the file.

+// Connected returns whether the SSE stream is currently connected.
 func (c *SSEMCPClient) Connected() bool {
 	return c.connected.Load()
 }

127-140: Consider adding a reconnection mechanism.

While the current changes correctly track connection status, there's no automatic reconnection mechanism when a disconnection is detected. Consider adding a method to attempt reconnection or providing guidance in documentation for how client code should handle ErrDisconnected.

// Connected returns whether the SSE stream is currently connected.
func (c *SSEMCPClient) Connected() bool {
	return c.connected.Load()
}

+// Reconnect attempts to reestablish the SSE connection.
+// Returns an error if reconnection fails.
+func (c *SSEMCPClient) Reconnect(ctx context.Context) error {
+	if c.Connected() {
+		return nil // Already connected
+	}
+	return c.Start(ctx)
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3dc35c and 9dd21cc.

📒 Files selected for processing (1)
  • client/sse.go (3 hunks)
🔇 Additional comments (6)
client/sse.go (6)

40-40: Good addition of thread-safe connection tracking.

The new connected field using atomic.Bool provides a thread-safe way to track the connection status, which will be essential for handling SSE stream disconnections.


43-47: Well-defined error variables improve error handling.

Replacing inline error messages with predefined error variables is a good practice. It makes the code more maintainable and allows callers to check for specific error types when handling disconnections.


127-128: Connection status correctly initialized.

Setting the connection status to true after the endpoint is received and the connection is fully established ensures accurate tracking of the client's readiness to process requests.


140-140: Properly handling disconnection events.

The deferred function that sets connected to false when readSSE ends is crucial for correctly tracking disconnections. This ensures that when the SSE stream ends (due to network issues or server-side closure), the client immediately updates its status.


286-288: Key improvement in request handling.

This check prevents sending requests when the connection is lost, which directly addresses the PR objective of handling SSE stream disconnections. By returning a specific error, client code can handle the disconnection appropriately and potentially attempt to reconnect.


279-284: Good use of predefined error variables.

Replacing inline error messages with the predefined error variables improves consistency and makes error handling more robust.

return nil
}

func (c *SSEMCPClient) Connected() bool {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unused; was the intention to use it in line 286?

Copy link

@JAORMX JAORMX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than the nit I pointed out in the code, the rest lgtm

@rwjblue-glean
Copy link
Collaborator

@mrene - Sorry for the delay here, I think this is a good addition and would love to land it if you have the time to fixup the merge conflicts?

It would also be great to get some tests for the new field (and possibly an explicit test for the case you really care about -- disconnection of the SSE then a subsequent request from the client). If the test is too onerous though, that's totally fine -- I just like having regression tests for this kind of thing to ensure we don't break it again in the future...

@rwjblue-glean rwjblue-glean added the status: needs submitter response Waiting for feedback from issue opener label May 11, 2025
@pottekkat pottekkat added type: bug Something isn't working as expected area: sdk SDK improvements unrelated to MCP specification labels May 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: sdk SDK improvements unrelated to MCP specification status: needs submitter response Waiting for feedback from issue opener type: bug Something isn't working as expected
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants