-
Notifications
You must be signed in to change notification settings - Fork 198
[vMCP] Define Session and SessionFactory interfaces (Phase 1) #3865
Description
Introduce the core interfaces and default implementations for the new session-scoped architecture described in THV-0038. This is purely additive — no changes to existing flows or existing tests.
New files:
pkg/vmcp/session/session.go—Sessioninterface (domain object:CallTool,ReadResource,GetPrompt,Tools,Resources,Prompts,BackendSessions,Close)pkg/vmcp/session/factory.go—SessionFactoryinterface anddefaultSessionFactorypkg/vmcp/session/default_session.go—defaultSessionembeddingtransportsession.Sessionfor metadata, owning backend clients in an internal map, tracking backend session IDs
Key requirements:
- Factory initializes clients per backend in parallel (
errgroup, bounded concurrency configurable viamax_backend_init_concurrency, default 10, per-session not global) - Per-backend timeout so a slow backend does not block session creation
- Partial initialization: log warnings for failed backends, continue with successful ones
- Thread safety:
sync.RWMutexprotecting client map;RLockreleased before network I/O;sync.WaitGroupin-flight counter soClose()waits for in-flight calls before tearing down clients Close()closes all owned backend clients
Dual-layer storage model:
defaultSession must cleanly separate two layers with different lifecycles:
| Layer | Contents | Storage | Lifetime |
|---|---|---|---|
| Metadata | Session ID, timestamps, identity reference, backend ID list | Serializable via transportsession.Storage interface (LocalStorage today, RedisStorage in future) |
Can persist across restarts |
| Runtime | MCP client objects, routing table, capabilities, backend session ID map, closed flag | In-process memory only — cannot be serialized (active TCP connections, goroutines) | Lives only while the vMCP instance is running |
The behavior-oriented Session embeds transportsession.Session (metadata layer) and owns MCP clients (runtime layer). All sessions go through the same Storage interface — no parallel storage path.
Distributed deployment note: because MCP clients cannot be serialized, horizontal scaling requires sticky sessions (session affinity at the load balancer). Without sticky sessions, a request routed to a different vMCP instance will need to recreate backend clients (one-time cost). This is a known trade-off and must be documented in the implementation.
Acceptance Criteria
-
Sessioninterface is defined inpkg/vmcp/session/session.gowith all required methods -
SessionFactoryinterface anddefaultSessionFactoryare defined and implemented -
defaultSessionimplements bothtransportsession.Sessionand the vMCPSessioninterface -
defaultSessioncleanly separates serializable metadata from non-serializable runtime state — no MCP client objects or routing tables are placed in the metadata layer - Session metadata is stored via the
transportsession.Storageinterface; no parallel storage path is introduced - The distributed deployment constraint (sticky sessions required) is documented in code comments or README
- Backend clients are initialized in parallel with bounded concurrency
- A slow or failing backend does not prevent the session from being created with the remaining backends
- All reads from the client map are protected by
RLockand locks are released before network I/O -
Close()waits for all in-flight operations to complete before closing backend clients - No changes to existing code or tests
- Unit tests cover:
CallTool,ReadResource,Close, parallel init with timeouts, partial failure, interface composition