pub struct LiveSessionRegistry { /* private fields */ }Expand description
Registry of live SessionActors for zeph serve (spec §9.3).
Distinct from the TUI’s own SessionRegistry/SlotId tab-switching abstraction
(zeph-tui/src/session.rs) — this is zeph serve-specific bookkeeping only. The internal
sessions mutex is never held across .await; Self::get_or_reactivate’s
reactivation_lock is a separate tokio::sync::Mutex deliberately held across .await for
its entire critical section — see that method’s doc comment.
Implementations§
Source§impl LiveSessionRegistry
impl LiveSessionRegistry
Sourcepub fn get(&self, id: &SessionId) -> Option<SessionActorHandle>
pub fn get(&self, id: &SessionId) -> Option<SessionActorHandle>
Look up a live session by id, refreshing its last_active timestamp on hit.
Sourcepub fn insert(&self, id: SessionId, handle: SessionActorHandle)
pub fn insert(&self, id: SessionId, handle: SessionActorHandle)
Register a freshly spawned actor’s handle, replacing (and dropping, without aborting) any prior entry under the same id.
Sourcepub async fn get_or_reactivate<F, Fut>(
&self,
id: &SessionId,
reactivate: F,
) -> Option<SessionActorHandle>
pub async fn get_or_reactivate<F, Fut>( &self, id: &SessionId, reactivate: F, ) -> Option<SessionActorHandle>
Look up a live session, reactivating it via reactivate if it isn’t currently live —
atomically, so two concurrent callers for the same absent id can never both win and
double-spawn a SessionActor over the same durable log (N1, impl-critic re-verify
finding: SessionEventLog is single-writer per INV-D2, and a plain get()-miss-then-
spawn-then-insert() sequence has no such guarantee under concurrency).
Fast path (the common case — session already live): a plain get(), no lock contention
with any in-flight reactivation elsewhere. Slow path (session absent): acquires
reactivation_lock, then re-checks get() under the lock — if a concurrent caller won
the race and already reactivated id while this caller was waiting for the lock, that
caller’s insert is visible here and reactivate is never invoked a second time. Only
the loser of the race skips calling reactivate; the winner runs it exactly once.
reactivate is expected to build+spawn the actor and insert it into self before
resolving — it runs to completion holding reactivation_lock, so its own insert is
safely serialized against any other concurrent get_or_reactivate call for the same
(or a different) id.
Sourcepub fn remove_if_current(
&self,
id: &SessionId,
tx: &Sender<SessionCommand>,
) -> Option<SessionActorHandle>
pub fn remove_if_current( &self, id: &SessionId, tx: &Sender<SessionCommand>, ) -> Option<SessionActorHandle>
Remove id’s entry only if it is still the exact handle identified by tx (compared via
mpsc::Sender::same_channel, which is true iff both senders share the same underlying
channel).
Used by SessionActor’s coordinator (M1) to reap its own registry entry on completion
without racing a concurrent reactivation (D-12) that has already inserted a fresh
handle under the same id — a plain remove(id) there would delete the new entry too, an
unconditional key-based removal cannot tell “my own now-dead entry” from “a different,
live entry that happens to share this id”.
Sourcepub fn remove(&self, id: &SessionId) -> Option<SessionActorHandle>
pub fn remove(&self, id: &SessionId) -> Option<SessionActorHandle>
Remove a session’s handle (used by idle eviction and explicit shutdown), returning it if present.
Sourcepub fn idle_candidates(&self, ttl: Duration) -> Vec<SessionId>
pub fn idle_candidates(&self, ttl: Duration) -> Vec<SessionId>
Session ids with no attached broadcast receivers (receiver_count() == 0) whose
last_active is at least ttl old — eviction candidates for a serve.evict task
(spec §9.3).
Trait Implementations§
Source§impl Default for LiveSessionRegistry
impl Default for LiveSessionRegistry
Source§fn default() -> LiveSessionRegistry
fn default() -> LiveSessionRegistry
Auto Trait Implementations§
impl !Freeze for LiveSessionRegistry
impl !RefUnwindSafe for LiveSessionRegistry
impl !UnwindSafe for LiveSessionRegistry
impl Send for LiveSessionRegistry
impl Sync for LiveSessionRegistry
impl Unpin for LiveSessionRegistry
impl UnsafeUnpin for LiveSessionRegistry
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request