Skip to content

Handle each session initialization separately #60

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

Merged
merged 1 commit into from
Mar 25, 2025

Conversation

torkve
Copy link
Contributor

@torkve torkve commented Mar 20, 2025

This removes global initialized flag, because each session can be initialized separately.

Summary by CodeRabbit

  • New Features
    • Improved session management now ensures that notifications are delivered only to fully active sessions, enhancing overall reliability.
    • Enhanced error handling prevents messages from being sent to sessions that aren’t completely set up, ensuring a more consistent update experience for users.
    • New methods introduced for session initialization, providing clearer management of session states.

Copy link
Contributor

coderabbitai bot commented Mar 20, 2025

Walkthrough

This pull request refactors session initialization across several server components. The changes add two new methods—Initialize() and Initialized() bool—to the session interfaces and structs, replacing the previous global atomic flag in the server. Client notification logic now verifies each session’s initialization state before proceeding. Test cases have been enhanced to validate the behavior of both initialized and uninitialized sessions.

Changes

Files Summary
server/server.go Added Initialize() and Initialized() bool to the ClientSession interface; removed the global atomic initialized flag; updated notification logic.
server/server_test.go Updated fakeSession with an initialized field and the new methods; added tests (including an "uninit session" case) to check session initialization.
server/sse.go, server/stdio.go Introduced an atomic.Bool field for session state and implemented Initialize() and Initialized() methods in both session structs.

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 (1)
server/server_test.go (1)

1095-1100: Implement ClientSession interface methods in fakeSession.

The Initialize method is empty since the test sets the initialized state directly, and the Initialized method correctly returns the state. Consider making Initialize set the flag to true for consistency with other implementations.

-func (f fakeSession) Initialize() {
+func (f fakeSession) Initialize() {
+    // Since fakeSession is a value type, this wouldn't update the receiver
+    // This is fine for tests, but in real implementations we use a pointer receiver
+    // or atomic operations to update the state
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 88fce3a and 47011cd.

📒 Files selected for processing (4)
  • server/server.go (6 hunks)
  • server/server_test.go (8 hunks)
  • server/sse.go (3 hunks)
  • server/stdio.go (3 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
server/server_test.go (2)
mcp/types.go (3) (3)
  • t (15-17)
  • t (19-30)
  • JSONRPCNotification (152-155)
server/server.go (2) (2)
  • MCPServer (75-88)
  • ClientSessionFromContext (63-68)
server/server.go (2)
server/stdio.go (9) (9)
  • s (58-60)
  • s (62-64)
  • s (66-68)
  • s (70-72)
  • s (95-97)
  • s (102-104)
  • s (109-187)
  • s (192-215)
  • s (219-234)
server/sse.go (7) (7)
  • s (33-35)
  • s (37-39)
  • s (41-43)
  • s (45-47)
  • s (146-153)
  • s (157-170)
  • s (174-255)
🔇 Additional comments (16)
server/sse.go (3)

11-11: Add sync/atomic import for atomic.Bool usage.

The import of "sync/atomic" is added to support the new atomic.Bool field for thread-safe access to the initialization state.


25-25: Add initialized state flag to sseSession.

Adding an atomic.Bool field ensures thread-safe operations on the initialization state flag, which is essential for concurrent access in an SSE server context.


41-47: Implement session initialization interface methods.

These methods properly implement the ClientSession interface, allowing for per-session initialization tracking. The atomic operations ensure thread-safety when accessing the initialization state.

server/stdio.go (3)

12-12: Add sync/atomic import for atomic.Bool usage.

The import of "sync/atomic" is required for the atomic.Bool field to ensure thread-safe operations on the initialization state.


55-55: Add initialized state flag to stdioSession.

Adding an atomic.Bool field provides thread-safe access to the initialization state, consistent with the implementation in sseSession.


66-72: Implement ClientSession interface methods.

These methods properly implement the required interface methods for session initialization, using atomic operations for thread safety.

server/server.go (6)

49-52: Add initialization methods to ClientSession interface.

These new interface methods formalize the contract for session initialization, allowing each session implementation to manage its own initialization state instead of using a global flag.


142-143: Check session initialization before sending notifications.

This change ensures that notifications are only sent to fully initialized sessions. This is important to prevent sending notifications to sessions that might not be ready to handle them yet.


160-162: Verify session initialization in SendNotificationToClient.

This change adds protection against sending notifications to uninitialized sessions, returning an appropriate error message. This helps clients understand when notifications can't be sent and why.


533-534: Update comment to reflect session initialization check.

The comment is updated to clarify that notifications are only sent to initialized sessions, which is consistent with the implementation changes.


553-554: Update comment for DeleteTools notification.

Similar to the previous comment update, this clarifies that DeleteTools notifications are only sent to initialized sessions.


617-619: Initialize client session when handling initialize request.

The server now initializes the client session directly rather than setting a global flag. This is the core change that enables per-session initialization tracking.

server/server_test.go (4)

183-183: Set session as initialized in test.

The test now properly sets the initialized state to true for the test session, ensuring that notifications can be sent to it.


210-226: Test both initialized and uninitialized sessions.

This test case now clearly distinguishes between initialized and uninitialized sessions, ensuring that the server correctly handles both types and only sends notifications to initialized sessions.


505-518: Add test case for uninitialized sessions.

This new test case verifies that attempting to send notifications to uninitialized sessions results in an error, which is important for validating the new behavior.


1084-1084: Add initialized field to fakeSession struct.

The fakeSession struct now includes the initialized flag to match the updated ClientSession interface requirements.

@torkve torkve force-pushed the per-session-initialize branch from 47011cd to 1d5b53c Compare March 25, 2025 03:43
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 (1)
server/server_test.go (1)

1180-1185: Simple implementation of the ClientSession interface

The implementation of the required Initialize() and Initialized() methods for the fakeSession struct allows for proper testing of the initialization logic, although Initialize() could be improved to actually update the initialized field state.

Consider updating the Initialize() method to set the initialized field to true:

func (f fakeSession) Initialize() {
+   f.initialized = true
}

However, since fakeSession is being used with value semantics in the tests rather than pointers, this change might not have any effect without also updating how the sessions are created and stored in the tests.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 47011cd and 1d5b53c.

📒 Files selected for processing (4)
  • server/server.go (6 hunks)
  • server/server_test.go (8 hunks)
  • server/sse.go (3 hunks)
  • server/stdio.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • server/stdio.go
  • server/sse.go
🧰 Additional context used
🧬 Code Definitions (1)
server/server.go (2)
server/stdio.go (9)
  • s (58-60)
  • s (62-64)
  • s (66-68)
  • s (70-72)
  • s (95-97)
  • s (102-104)
  • s (109-187)
  • s (192-215)
  • s (219-234)
server/sse.go (7)
  • s (34-36)
  • s (38-40)
  • s (42-44)
  • s (46-48)
  • s (161-168)
  • s (172-185)
  • s (189-265)
🔇 Additional comments (10)
server/server.go (6)

50-53: Appropriate interface extension to support per-session initialization

The addition of Initialize() and Initialized() bool methods to the ClientSession interface is a well-designed approach that decouples session state management from the server, allowing each session type to handle its initialization state independently.


206-207: Good safeguard for notification delivery

The condition to check session.Initialized() before sending notifications prevents sending data to sessions that aren't ready to process it, which is a robust defensive programming practice.


225-225: Enhanced error handling for client notifications

The additional check for !session.Initialized() aligns with the PR objective of handling each session independently and ensures notifications are only sent to properly initialized sessions.


413-414: Clear notification comment improvement

The updated comment clarifies that notifications are only sent to initialized sessions, which matches the implementation and improves code readability.


433-434: Consistent notification comment improvement

This comment mirrors the one on line 413-414, maintaining consistency throughout the codebase when referring to the same behavior.


497-499: Per-session initialization implementation

This change correctly replaces the previous global initialization flag with per-session initialization, ensuring that each session can be managed independently as intended by the PR objective.

server/server_test.go (4)

184-184: Tests properly initialize active sessions

The test cases appropriately set the initialized field to true for active sessions, ensuring they receive notifications as expected.

Also applies to: 215-215, 223-224, 257-257


219-225: Good test coverage for uninitialized sessions

Adding test cases for uninitialized sessions is important for validating that the new initialization check works correctly by preventing notification delivery to sessions that aren't ready.


505-519: Comprehensive test for uninitialized session notifications

This test properly verifies that attempting to send a notification to an uninitialized session results in an error, ensuring the defensive check in SendNotificationToClient works as intended.


1169-1169: Proper field addition to the fakeSession struct

The addition of the initialized boolean field to the fakeSession struct enables proper testing of the initialization state management.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants