pub struct StateManager { /* private fields */ }Expand description
State manager for pending generation sessions.
Uses an in-memory HashMap protected by RwLock for thread-safe access.
Sessions expire after 30 minutes and are cleaned up lazily.
§Examples
use mcp_execution_server::state::StateManager;
use mcp_execution_server::types::PendingGeneration;
use mcp_execution_server::clock::SystemClock;
use mcp_execution_core::{ServerId, ServerConfig};
use mcp_execution_introspector::ServerInfo;
let state = StateManager::new();
let pending = PendingGeneration::new(
ServerId::new("github").unwrap(),
server_info,
ServerConfig::builder().command("npx".to_string()).build().unwrap(),
None,
&SystemClock,
);
// Store and get session ID
let session_id = state.store(pending).await.unwrap();
// Retrieve session data
let retrieved = state.take(session_id).await;
assert!(retrieved.is_some());Implementations§
Source§impl StateManager
impl StateManager
Sourcepub async fn store(
&self,
generation: PendingGeneration,
) -> Result<Uuid, StateError>
pub async fn store( &self, generation: PendingGeneration, ) -> Result<Uuid, StateError>
Stores a pending generation and returns a session ID.
This operation also performs lazy cleanup of expired sessions.
§Errors
Returns StateError::AtCapacity if the pending-session table is already at
MAX_PENDING_SESSIONS after expired sessions have been swept, or
StateError::MemoryBudgetExceeded if storing this session would push the aggregate
approximate memory footprint of all pending sessions past MAX_TOTAL_PENDING_BYTES.
§Examples
use mcp_execution_server::state::StateManager;
let state = StateManager::new();
let session_id = state.store(pending).await.unwrap();Sourcepub async fn take(&self, session_id: Uuid) -> Option<PendingGeneration>
pub async fn take(&self, session_id: Uuid) -> Option<PendingGeneration>
Retrieves and removes a pending generation.
Returns None if the session is not found or has expired.
This operation also performs lazy cleanup of expired sessions.
§Examples
use mcp_execution_server::state::StateManager;
let state = StateManager::new();
let session_id = state.store(pending).await.unwrap();
let retrieved = state.take(session_id).await;
assert!(retrieved.is_some());
// Second take returns None (already removed)
let second = state.take(session_id).await;
assert!(second.is_none());Sourcepub async fn get(&self, session_id: Uuid) -> Option<PendingGeneration>
pub async fn get(&self, session_id: Uuid) -> Option<PendingGeneration>
Gets a pending generation without removing it.
Returns None if the session is not found or has expired.
§Examples
use mcp_execution_server::state::StateManager;
let state = StateManager::new();
let session_id = state.store(pending).await.unwrap();
// Get without removing
let peeked = state.get(session_id).await;
assert!(peeked.is_some());
// Still available
let peeked_again = state.get(session_id).await;
assert!(peeked_again.is_some());Sourcepub async fn pending_count(&self) -> usize
pub async fn pending_count(&self) -> usize
Returns the current pending session count (excluding expired).
§Examples
use mcp_execution_server::state::StateManager;
let state = StateManager::new();
assert_eq!(state.pending_count().await, 0);Sourcepub async fn cleanup_expired(&self) -> usize
pub async fn cleanup_expired(&self) -> usize
Cleans up all expired sessions.
Returns the number of sessions that were removed.
§Examples
use mcp_execution_server::state::StateManager;
let state = StateManager::new();
let removed = state.cleanup_expired().await;
assert_eq!(removed, 0);