pub struct SessionRegistry { /* private fields */ }Expand description
Manages active sessions.
§Locking design (lock C)
Uses tokio::sync::Mutex because feed_response holds the lock
while calling Session::feed_one() (which itself acquires the
per-session std::sync::Mutex<SessionStatus>, lock A). The lock
ordering invariant is always C → A — no code path acquires A
then C, so deadlock is structurally impossible.
tokio::sync::Mutex is chosen here (rather than std::sync::Mutex)
because feed_response must take the session out of the map for
the async wait_event() call. The two-phase pattern (lock → remove
→ unlock → await → lock → reinsert) requires an async-aware mutex
to avoid holding the lock across the wait_event().await.
§Contention
list_snapshots() (from alc_status) holds lock C while iterating
all sessions. During this time, feed_response for any session is
blocked. Given that snapshot iteration is O(n) with n = active
sessions (typically 1–3) and each snapshot takes microseconds, this
is acceptable. If session count grows significantly, consider
switching to a concurrent map or per-session locks.
§Interaction with lock A
Session::snapshot() (called under lock C in list_snapshots)
acquires lock A via ExecutionMetrics::snapshot(). This is safe:
- Lock order: C → A (consistent with
feed_response) - Lock A hold time: microseconds (JSON field reads)
- Lock A is per-session (no cross-session contention)
Implementations§
Source§impl SessionRegistry
impl SessionRegistry
pub fn new() -> Self
Sourcepub async fn start_execution(
&self,
session: Session,
) -> Result<(String, FeedResult), SessionError>
pub async fn start_execution( &self, session: Session, ) -> Result<(String, FeedResult), SessionError>
Start execution and wait for first event (pause or completion).
Sourcepub async fn feed_response(
&self,
session_id: &str,
query_id: &QueryId,
response: String,
) -> Result<FeedResult, SessionError>
pub async fn feed_response( &self, session_id: &str, query_id: &QueryId, response: String, ) -> Result<FeedResult, SessionError>
Feed one response to a paused session by query_id.
If this completes all pending queries, the session resumes and returns the next event (Paused or Finished). If queries remain, returns Accepted { remaining }.
Sourcepub async fn list_snapshots(&self) -> HashMap<String, Value>
pub async fn list_snapshots(&self) -> HashMap<String, Value>
Snapshot all active sessions for external observation (alc_status).
Returns a map of session_id → snapshot JSON. Only includes sessions currently held in the registry (i.e. paused, awaiting responses). Sessions that have completed are already removed from the registry.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for SessionRegistry
impl !RefUnwindSafe for SessionRegistry
impl Send for SessionRegistry
impl Sync for SessionRegistry
impl Unpin for SessionRegistry
impl UnsafeUnpin for SessionRegistry
impl !UnwindSafe for SessionRegistry
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<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