Claude SDK Session Manager - Pure dependency injection architecture.
This module provides a SessionManager class that encapsulates session pool lifecycle
management using dependency injection patterns without any global state.
SessionManager
SessionManager(settings, metrics_factory=None)
Manages the lifecycle of session-based Claude SDK clients with dependency injection.
Parameters:
Name |
Type |
Description |
Default |
settings
|
Settings
|
Optional settings containing session pool configuration
|
required
|
metrics_factory
|
MetricsFactory | None
|
Optional callable that returns a metrics instance.
If None, no metrics will be used.
|
None
|
Source code in ccproxy/claude_sdk/manager.py
| def __init__(
self,
settings: Settings,
metrics_factory: MetricsFactory | None = None,
) -> None:
"""Initialize SessionManager with optional settings and metrics factory.
Args:
settings: Optional settings containing session pool configuration
metrics_factory: Optional callable that returns a metrics instance.
If None, no metrics will be used.
"""
import structlog
logger = structlog.get_logger(__name__)
self._settings = settings
self._session_pool: SessionPool | None = None
self._lock = asyncio.Lock()
self._metrics_factory = metrics_factory
# Initialize session pool if enabled
session_pool_enabled = self._should_enable_session_pool()
logger.debug(
"session_manager_init",
has_settings=bool(settings),
has_metrics_factory=bool(metrics_factory),
session_pool_enabled=session_pool_enabled,
)
if session_pool_enabled:
self._session_pool = SessionPool(settings.claude.sdk_session_pool)
logger.info(
"session_manager_session_pool_initialized",
session_ttl=self._session_pool.config.session_ttl,
max_sessions=self._session_pool.config.max_sessions,
cleanup_interval=self._session_pool.config.cleanup_interval,
)
else:
logger.debug(
"session_manager_session_pool_skipped",
reason="session_pool_disabled_in_settings",
)
|
is_active
property
Check if the session manager has an active session pool.
start
async
Start the session manager and session pool.
Source code in ccproxy/claude_sdk/manager.py
| async def start(self) -> None:
"""Start the session manager and session pool."""
if self._session_pool:
await self._session_pool.start()
|
shutdown
async
Gracefully shuts down the session pool.
This method is idempotent - calling it multiple times is safe.
Source code in ccproxy/claude_sdk/manager.py
| async def shutdown(self) -> None:
"""Gracefully shuts down the session pool.
This method is idempotent - calling it multiple times is safe.
"""
async with self._lock:
# Close session pool
if self._session_pool:
await self._session_pool.stop()
self._session_pool = None
|
get_session_client
async
get_session_client(session_id, options)
Get session-aware client.
Source code in ccproxy/claude_sdk/manager.py
| async def get_session_client(
self,
session_id: str,
options: ClaudeCodeOptions,
) -> SessionClient:
"""Get session-aware client."""
logger = structlog.get_logger(__name__)
logger.debug(
"session_manager_get_session_client",
session_id=session_id,
has_session_pool=bool(self._session_pool),
)
if not self._session_pool:
logger.error(
"session_manager_session_pool_unavailable",
session_id=session_id,
)
raise ClaudeProxyError(
message="Session pool not available",
error_type="configuration_error",
status_code=500,
)
return await self._session_pool.get_session_client(session_id, options)
|
interrupt_session
async
interrupt_session(session_id)
Interrupt a specific session due to client disconnection.
Parameters:
Name |
Type |
Description |
Default |
session_id
|
str
|
The session ID to interrupt
|
required
|
Returns:
Type |
Description |
bool
|
True if session was found and interrupted, False otherwise
|
Source code in ccproxy/claude_sdk/manager.py
| async def interrupt_session(self, session_id: str) -> bool:
"""Interrupt a specific session due to client disconnection.
Args:
session_id: The session ID to interrupt
Returns:
True if session was found and interrupted, False otherwise
"""
if not self._session_pool:
logger.warning(
"session_manager_interrupt_session_no_pool",
session_id=session_id,
)
return False
logger.info(
"session_manager_interrupt_session",
session_id=session_id,
)
return await self._session_pool.interrupt_session(session_id)
|
interrupt_all_sessions
async
Interrupt all active sessions (for shutdown or emergency cleanup).
Returns:
Type |
Description |
int
|
Number of sessions that were interrupted
|
Source code in ccproxy/claude_sdk/manager.py
| async def interrupt_all_sessions(self) -> int:
"""Interrupt all active sessions (for shutdown or emergency cleanup).
Returns:
Number of sessions that were interrupted
"""
if not self._session_pool:
logger.warning("session_manager_interrupt_all_no_pool")
return 0
logger.info("session_manager_interrupt_all_sessions")
return await self._session_pool.interrupt_all_sessions()
|
get_session_pool_stats
async
Get session pool statistics.
Source code in ccproxy/claude_sdk/manager.py
| async def get_session_pool_stats(self) -> dict[str, Any]:
"""Get session pool statistics."""
if not self._session_pool:
return {"enabled": False}
return await self._session_pool.get_stats()
|
reset_for_testing
Synchronous reset for test environments.
Warning
This method should only be used in tests. It does not properly
shut down the session pool - use shutdown() for production code.
Source code in ccproxy/claude_sdk/manager.py
| def reset_for_testing(self) -> None:
"""Synchronous reset for test environments.
Warning:
This method should only be used in tests. It does not properly
shut down the session pool - use shutdown() for production code.
"""
self._session_pool = None
|
has_session_pool
async
Check if session pool is available and enabled.
Source code in ccproxy/claude_sdk/manager.py
| async def has_session_pool(self) -> bool:
"""Check if session pool is available and enabled."""
return self._session_pool is not None and self._session_pool.config.enabled
|
has_session
async
Check if a session exists in the session pool.
Parameters:
Name |
Type |
Description |
Default |
session_id
|
str
|
|
required
|
Returns:
Type |
Description |
bool
|
True if session exists, False otherwise
|
Source code in ccproxy/claude_sdk/manager.py
| async def has_session(self, session_id: str) -> bool:
"""Check if a session exists in the session pool.
Args:
session_id: The session ID to check
Returns:
True if session exists, False otherwise
"""
if not self._session_pool:
return False
return await self._session_pool.has_session(session_id)
|