You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: Add pluggable storage backend for session management (#1989)
* feat: Add pluggable storage backend for session management
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]>
* Address PR feedback: fix race condition and encapsulation issues
- 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]>
* Fix incorrect string conversion in test session ID generation
- 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]>
* Address PR feedback: improve session storage interface design
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]>
---------
Signed-off-by: Juan Antonio Osorio <[email protected]>
Co-authored-by: Claude <[email protected]>
0 commit comments