-
Notifications
You must be signed in to change notification settings - Fork 126
feat: Add pluggable storage backend for session management #1989
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
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1989 +/- ##
==========================================
+ Coverage 48.71% 49.07% +0.36%
==========================================
Files 241 243 +2
Lines 30592 30756 +164
==========================================
+ Hits 14902 15095 +193
+ Misses 14567 14530 -37
- Partials 1123 1131 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the session management system to use a pluggable storage interface, enabling future support for distributed storage backends like Redis/Valkey while maintaining backward compatibility with the existing in-memory behavior.
Key changes:
- Introduced a
Storage
interface that abstracts session persistence operations - Refactored
Manager
to use the Storage interface instead of directly usingsync.Map
- Added JSON serialization support for sessions to enable future network storage
- Enhanced session interfaces with metadata and data management methods
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
File | Description |
---|---|
pkg/transport/session/storage.go | New Storage interface defining core operations for session persistence |
pkg/transport/session/storage_local.go | LocalStorage implementation using sync.Map for backward compatibility |
pkg/transport/session/serialization.go | JSON serialization functions for future distributed storage support |
pkg/transport/session/manager.go | Refactored Manager to use Storage interface instead of direct sync.Map |
pkg/transport/session/storage_test.go | Comprehensive test suite for storage implementations and serialization |
pkg/transport/session/serialization_test.go | Test suite for JSON serialization/deserialization functionality |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
sseSession := NewSSESession(sd.ID) | ||
// Update timestamps to match stored values | ||
sseSession.created = sd.CreatedAt | ||
sseSession.updated = sd.UpdatedAt |
Copilot
AI
Sep 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct field assignment bypasses encapsulation and could break if the internal structure changes. Consider adding setter methods or using reflection-based copying instead of direct field access.
sseSession.updated = sd.UpdatedAt | |
sseSession.SetUpdatedAt(sd.UpdatedAt) |
Copilot uses AI. Check for mistakes.
@claude please review this thoroguhly |
Claude finished @JAORMX's task —— View job Thorough Review of PR #1989Completed comprehensive review of the session storage refactoring. Tasks
🎯 Overall AssessmentThis is a well-designed refactoring that successfully introduces a pluggable storage interface while maintaining backward compatibility. The code quality is high, test coverage is comprehensive, and the architecture is solid. However, there are several issues that need attention before merging. 🔴 Critical Issues1. Race Condition in
|
a0ba465
to
30db7d3
Compare
@claude please review this again |
Claude finished @JAORMX's task —— View job Thorough Code Review: Session Storage RefactoringI've completed a comprehensive review of all 8 changed files (1,089 additions, 54 deletions). Here are my findings: ✅ Excellent Improvements Since Last ReviewI can see that all critical issues from the previous review have been addressed:
🎯 Architecture & Design QualityStrengths
Design Observations1. Manager methods coupled to func (m *Manager) Range(f func(key, value interface{}) bool) {
if localStorage, ok := m.storage.(*LocalStorage); ok {
localStorage.Range(f)
}
}
2. Context usage in Manager (manager.go:128-171)
func (m *Manager) GetContext(ctx context.Context, id string) (Session, bool)
🔍 Code Quality AnalysisThread Safety ✅
Error Handling ✅
Test Coverage ✅
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
@claude can you review this again? |
Claude finished @JAORMX's task —— View job Code Review: Session Storage RefactoringCompleted comprehensive review of PR #1989 - Pluggable storage backend for session management. Review Tasks
🎯 Overall AssessmentThis is an excellent refactoring that successfully introduces a pluggable storage interface while maintaining full backward compatibility. All critical issues from previous reviews have been addressed. The code quality is high, test coverage is comprehensive (89.56%), and the architecture is well-designed. ✅ Previous Issues - All FixedI verified that all critical issues from the previous review have been properly addressed:
🟢 Code Quality ReviewArchitecture & Design: Excellent ⭐Strengths:
Minor Design Notes (not blockers):
Thread Safety: Excellent ✅All session types properly implement thread safety:
Error Handling: Excellent ✅
Test Coverage: Excellent ✅89.56% patch coverage is outstanding for new code! Tests comprehensively cover:
|
Refactors the session management system to use a pluggable storage interface, enabling future support for distributed storage backends like Redis/Valkey while maintaining backward compatibility. What Changed - Introduced a Storage interface that abstracts session persistence - Refactored Manager to use the Storage interface instead of directly using sync.Map - Created LocalStorage implementation that maintains the existing in-memory behavior - Added JSON serialization support for sessions to enable future network storage - Extended Session interface with Type() and metadata methods that were already implemented in concrete types Why The previous implementation was tightly coupled to in-memory storage, making it impossible to share sessions across multiple ToolHive instances. This refactoring enables: - Horizontal scaling with shared session state - Session persistence across restarts - Future Redis/Valkey backend support without breaking changes Testing Added comprehensive unit tests covering: - LocalStorage implementation - Session serialization/deserialization - Manager with pluggable storage - All existing session types (ProxySession, SSESession, StreamableSession) All tests pass and the implementation maintains full backward compatibility. Signed-off-by: Juan Antonio Osorio <[email protected]>
- Fix race condition in LocalStorage.Close() by collecting keys before deletion - Update Close() comment to reflect actual behavior (clears sessions, not a no-op) - Add setter methods (setTimestamps, setMetadataMap) to ProxySession for proper encapsulation - Update serialization to use setter methods instead of direct field access - Fix StreamableSession constructor to use NewTypedProxySession for proper initialization - Add type assertion check in StreamableSession deserialization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Replace string(rune('a' + i)) with fmt.Sprintf("session-%d", i) - Previous approach only worked for i values 0-25 and produced unexpected Unicode characters for larger values - Add fmt import to storage_test.go 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
4e12c30
to
a8ebd91
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added some comments
This commit addresses all feedback from PR review comments: 1. Separate Touch from Load operations - Remove auto-touch behavior from Storage.Load() - Manager.Get() now explicitly touches sessions - Gives callers control over when sessions are touched 2. Document Range/Count design decision - Add comprehensive documentation explaining why Range/Count are not part of Storage interface - These operations don't make sense for distributed storage 3. Add consistent context timeout usage - All storage operations now use consistent timeouts - 5 seconds for quick operations (Get, Delete, Add) - 30 seconds for cleanup operations 4. Proper error handling throughout - Manager.Delete() and Manager.Stop() now return errors - Cleanup routine logs errors instead of ignoring them - Proxy implementations use debug logging for non-critical errors All tests pass with these changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Overview
Refactors the session management system to use a pluggable storage interface, enabling future support for distributed storage backends like Redis/Valkey while maintaining backward compatibility.
What Changed
Core Architecture
Storage
interface that abstracts session persistence operationsManager
to use the Storage interface instead of directly usingsync.Map
LocalStorage
implementation that maintains the existing in-memory behaviorSession Interface Enhancements
Session
interface withType()
and metadata methods that were already implemented in concrete typesGetData()
,SetData()
,GetMetadata()
, andSetMetadata()
methods for better data managementNew Components
Storage
interface with methods:Store()
,Load()
,Delete()
,DeleteExpired()
,Close()
LocalStorage
implementation usingsync.Map
for backward compatibilitySessionType
enum for better type identificationWhy This Change?
The previous implementation was tightly coupled to in-memory storage, making it impossible to share sessions across multiple ToolHive instances. This refactoring enables:
Testing
Added comprehensive unit tests covering:
LocalStorage
implementation with all CRUD operationsManager
with pluggable storage interfaceProxySession
,SSESession
,StreamableSession
)Backward Compatibility
✅ Full backward compatibility maintained
NewManager()
function continues to work unchangedFiles Changed
pkg/transport/session/manager.go
- Refactored to use Storage interfacepkg/transport/session/storage.go
- New Storage interface and LocalStorage implementationpkg/transport/session/serialization.go
- JSON serialization supportpkg/transport/session/session.go
- Enhanced session types with metadata supportpkg/transport/session/storage_test.go
- Comprehensive test suitepkg/transport/session/serialization_test.go
- Serialization testsFuture Work
This foundation enables:
Checklist