pub struct SessionRegistry {
pub sessions: RwLock<HashMap<String, Arc<Mutex<Session>>>>,
/* private fields */
}Fields§
§sessions: RwLock<HashMap<String, Arc<Mutex<Session>>>>Implementations§
Source§impl SessionRegistry
impl SessionRegistry
pub fn new() -> SessionRegistry
pub fn with_persistence<P>(dir: P) -> Result<SessionRegistry, Error>
Sourcepub async fn persist_snapshot(&self) -> Result<(), Error>
pub async fn persist_snapshot(&self) -> Result<(), Error>
Snapshot every session (locking each briefly) and persist. Never holds the map lock across the per-session locks or the fs write.
Clone the shared handle for a session (brief map read; no session lock).
pub async fn get_session(&self, session_id: &str) -> Option<Session>
Sourcepub async fn get_all_sessions(&self) -> Vec<Session>
pub async fn get_all_sessions(&self) -> Vec<Session>
Deep-clones every registered session into one Vec, and therefore
holds the whole registry resident for as long as the caller keeps the
result. Only for one-shot, non-streaming work whose lifetime is its own
call (the shutdown snapshot in src/main.rs). A caller that emits the
sessions to a client — where the Vec stays alive for the duration of a
client-paced stream, times the number of concurrent streams — must use
SessionRegistry::shared_sessions instead and lock one handle at a
time, which keeps one Session clone resident.
A snapshot of every registered session’s shared handle, in unspecified order.
One synchronous pass under the map read lock, cloning
SharedSession pointers only — never a Session. This is the
entry point for a traversal that wants to visit every session without
materializing them all at once: take the handles here, then lock and
clone them one at a time (see watch_sync in macp-runtime, which uses
exactly that shape for the WatchSessions initial sync).
Unlike an ID list, this is a true snapshot of the session set: a
handle keeps its Session reachable even after the registry entry is
removed, so a traversal in progress sees every session that was
registered when the snapshot was taken, exactly once, whatever happens
to the map afterwards. Removal is never blocked — eviction takes the
write lock and removes unconditionally; only the deallocation of an
evicted session waits for the last handle to drop. The cost is one
pointer per session, against the ~8x larger String an ID list would
clone.
Sessions registered after the snapshot are absent from it, and a snapshotted session’s contents can still change under its mutex — the snapshot fixes the set, not the state.
Per the lock-ordering contract above, the map lock is released before any session mutex is taken: this returns handles and never locks one.
Sourcepub async fn session_ids_after(
&self,
after: Option<&str>,
limit: usize,
) -> Vec<String>
pub async fn session_ids_after( &self, after: Option<&str>, limit: usize, ) -> Vec<String>
Session IDs strictly greater than after, ascending (byte order), at most
limit. Keyset cursor primitive for ListSessions paging (see plan D1/D2).
Holds only the map read lock, for one synchronous pass — no session mutex is
taken and no .await happens under the guard, per the lock-ordering contract
documented above (map lock BEFORE session mutex; never hold the map lock
across an await).
Each call is individually consistent, but a multi-page traversal is not a snapshot: the lock is released between pages, so concurrent mutation is visible mid-traversal. A session inserted at a key at or below the cursor is missed by the remainder of the traversal; one inserted above the cursor appears in a later page; one removed above the cursor is never emitted. Already-emitted IDs are stable — the cursor only moves forward — so no ID is ever returned twice. This is inherent to keyset paging; callers must not present a completed traversal as a point-in-time view of the registry.
limit is caller-supplied and may be arbitrarily large (usize::MAX reads
as “no limit”); allocation is bounded by the map, never by the limit.
pub async fn insert_recovered_session( &self, session_id: String, session: Session, )
pub async fn count_open_sessions_for_initiator(&self, sender: &str) -> usize
Trait Implementations§
Source§impl Default for SessionRegistry
impl Default for SessionRegistry
Source§fn default() -> SessionRegistry
fn default() -> SessionRegistry
Auto Trait Implementations§
impl !Freeze for SessionRegistry
impl !RefUnwindSafe for SessionRegistry
impl !UnwindSafe for SessionRegistry
impl Send for SessionRegistry
impl Sync for SessionRegistry
impl Unpin for SessionRegistry
impl UnsafeUnpin 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> 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