pub struct ServerState {
pub journal_dir: PathBuf,
pub sessions: Mutex<HashMap<String, Arc<ClientSession>>>,
pub inference: OnceLock<Arc<InferenceEngine>>,
pub host: Arc<HostState>,
pub shared_memgine: Option<Arc<Mutex<MemgineEngine>>>,
pub voice_sessions: Arc<VoiceSessionRegistry>,
pub meetings: Arc<MeetingRegistry>,
pub a2ui: A2uiSurfaceStore,
pub admission: Arc<InferenceAdmission>,
pub a2ui_route_auth: Mutex<HashMap<String, A2aRouteAuth>>,
}Expand description
Global server state shared across all connections.
Fields§
§journal_dir: PathBuf§sessions: Mutex<HashMap<String, Arc<ClientSession>>>§inference: OnceLock<Arc<InferenceEngine>>§host: Arc<HostState>When Some, create_session clones this handle into every new
ClientSession.memgine — embedders that want a single shared
memgine across all WS sessions set this. Standalone car-server
leaves it None, which gives each session its own engine
(preserving today’s behavior).
voice_sessions: Arc<VoiceSessionRegistry>Process-wide voice session registry. Each
voice.transcribe_stream.start call registers its own per-client
WsVoiceEventSink so events route back to the originating WS
connection only.
meetings: Arc<MeetingRegistry>Process-wide meeting registry. Meeting ids are global; each
meeting binds to the originating client’s WS for upstream
events but persists transcripts to the resolved
.car/meetings/<id>/ regardless of which client started it.
a2ui: A2uiSurfaceStoreProcess-wide A2UI surface store. Agent-produced surfaces are visible to every host UI subscriber, independent of the WebSocket session that applied the update.
admission: Arc<InferenceAdmission>Process-wide concurrency gate for inference RPC handlers. Sized
from host RAM at startup, overridable via
crate::admission::ENV_MAX_CONCURRENT. Without this, N
concurrent users multiply KV-cache and activation memory and
take the host out (#114-adjacent: filed alongside the daemon
always-on rework). The semaphore lives on ServerState so it
is shared across every WebSocket session in the same process.
a2ui_route_auth: Mutex<HashMap<String, A2aRouteAuth>>Server-side A2A continuation auth keyed by A2UI surface id.
Kept out of A2uiSurface.owner so host renderers never see
bearer/API-key material.
Implementations§
Source§impl ServerState
impl ServerState
Sourcepub fn standalone(journal_dir: PathBuf) -> Self
pub fn standalone(journal_dir: PathBuf) -> Self
Constructor for the standalone car-server binary. Each WS
connection gets its own per-session memgine — matches the
pre-extraction default and is correct for a single-process
daemon serving one user at a time.
Embedders must not call this. It silently leaves
shared_memgine = None, which re-introduces the dual-memgine
bug U7 was created to prevent (one engine in the embedder, a
fresh one inside every WS session). Embedders use
ServerState::embedded instead, which makes the shared
engine handle a required argument so it cannot be forgotten.
Sourcepub fn embedded(
journal_dir: PathBuf,
shared_memgine: Arc<Mutex<MemgineEngine>>,
) -> Self
pub fn embedded( journal_dir: PathBuf, shared_memgine: Arc<Mutex<MemgineEngine>>, ) -> Self
Constructor for embedders (e.g. tokhn-daemon). The shared
memgine handle is required: every WS session created by
this state will reuse the same engine, preventing the
dual-memgine bug.
For embedders that also want to inject a pre-warmed inference
engine or other advanced wiring, build a ServerStateConfig
directly and call ServerState::with_config.
Sourcepub fn with_config(cfg: ServerStateConfig) -> Self
pub fn with_config(cfg: ServerStateConfig) -> Self
Build a ServerState from a ServerStateConfig — the path
embedders use when they need to inject a shared memgine and
a pre-warmed inference engine, or any other advanced wiring
the convenience constructors don’t cover.
pub async fn create_session( &self, client_id: &str, channel: Arc<WsChannel>, ) -> Arc<ClientSession>
Sourcepub async fn remove_session(
&self,
client_id: &str,
) -> Option<Arc<ClientSession>>
pub async fn remove_session( &self, client_id: &str, ) -> Option<Arc<ClientSession>>
Remove a per-client session from the registry on disconnect.
Returns the removed session if present so callers can drop any
remaining strong refs (e.g. drain pending tool callbacks). Fix
for MULTI-4 / WS-3 — without this, state.sessions retains
Arc<ClientSession> for every connection that ever existed.
Auto Trait Implementations§
impl !Freeze for ServerState
impl !RefUnwindSafe for ServerState
impl Send for ServerState
impl Sync for ServerState
impl Unpin for ServerState
impl UnsafeUnpin for ServerState
impl !UnwindSafe for ServerState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more