pub struct SessionRegistry { /* private fields */ }Expand description
The session registry.
Implementations§
Source§impl SessionRegistry
impl SessionRegistry
Sourcepub fn get_or_open(
&self,
id: &str,
workflow: Workflow,
identity: &AgentIdentity,
breaker: &BreakerConfig,
) -> Arc<Session>
pub fn get_or_open( &self, id: &str, workflow: Workflow, identity: &AgentIdentity, breaker: &BreakerConfig, ) -> Arc<Session>
Get or open a session.
If an entry exists but has completed close (receipt/ATIF durably
committed, journal removed) and has not yet been reaped by the
idle sweeper, treat the id as free and open a fresh session —
otherwise a well-behaved client that reuses a session id after a
server-side close (retry after a 5xx, network partition, TTL
refresh) would see 400 session is already closed for the entire
eviction window. A session that started close but has not yet
finished it (close_complete = 0) is not replaced: reopening
would race the in-flight close and split the audit trail.
This is the right shape for chat requests: the client is
starting a new turn and it’s fine to give them a fresh state
under the same id. For tool interception, use
Self::get_or_open_no_reopen — a tool call references an
in-progress conversation, and silently resurrecting a closed
session would let the client extend the audit trail past its
signed receipt.
Sourcepub fn get_or_open_no_reopen(
&self,
id: &str,
workflow: Workflow,
identity: &AgentIdentity,
breaker: &BreakerConfig,
) -> Arc<Session>
pub fn get_or_open_no_reopen( &self, id: &str, workflow: Workflow, identity: &AgentIdentity, breaker: &BreakerConfig, ) -> Arc<Session>
Like Self::get_or_open but hand back the existing session
without recycling completed-close entries — the caller then
sees is_closed() == true and can refuse with BadRequest.
Use this on paths where the caller is trying to extend an
existing session (tool interception, session-scoped mutations).
Sourcepub fn insert_recovered(&self, session: Session) -> Arc<Session>
pub fn insert_recovered(&self, session: Session) -> Arc<Session>
Insert a session reconstructed from durable spool state.
Sourcepub fn try_insert_recovered(
&self,
session: Session,
) -> Result<Arc<Session>, Arc<Session>>
pub fn try_insert_recovered( &self, session: Session, ) -> Result<Arc<Session>, Arc<Session>>
Insert a recovered session only if the id is not already registered.
Returns Err(existing) on collision so recovery does not clobber a
concurrently-opened active session — the recovery loop must not run
finalize on the returned Arc when it happens to be the live one.
Sourcepub fn evict_finalized(&self, idle_s: u64) -> Vec<Arc<Session>>
pub fn evict_finalized(&self, idle_s: u64) -> Vec<Arc<Session>>
Evict signed sessions whose close ran to full completion and that
have been idle longer than idle_s, returning the evicted sessions.
Only signed sessions whose close fully completed are eligible: a
completed close removed the on-disk journal, so nothing re-inserts
them, and a later request or lifecycle call for the id behaves
exactly as it would after a process restart. close_complete (not
artifact_committed, which is set before the fallible bridge emits
and journal removal) is the gate — a failed or in-flight close must
stay resident, or a client reusing the id could open a fresh session
whose journal appends collide with the still-on-disk records.
Unsigned sessions must stay resident — the recovery scan re-inserts
them from their spool artifact on the next tick anyway, and evicting
one lets a client reuse its id against the still-present artifact and
provenance files, poisoning the new incarnation’s close. Capture-failed
(quarantined) sessions also stay: they are bounded by real crash
events and their in-registry seal is what keeps the fail-closed
refusal cheap. Without eviction the registry grows by one entry per
client-chosen session id for the process lifetime.
Sourcepub fn pending_close_sessions(&self) -> Vec<Arc<Session>>
pub fn pending_close_sessions(&self) -> Vec<Arc<Session>>
Round-43 F1: sessions where close_session_locked marked
artifact_committed = 1 but crashed / failed before running
the finalization tail (emit_bridge_event(SESSION_CLOSE) +
remove_step_journal + remove_lifecycle_outbox +
mark_close_complete). Without this recovery hook such
sessions accumulate in the registry forever: is_closed() is
true so the idle sweeper skips them; close_complete = 0 so
evict_finalized refuses them; recovery scans skip them via
the “already in registry” short-circuit. Capture-failed and
empty-unsigned quarantines are excluded — they intentionally
stay in the registry as evidence of the incident.
Round-44 F2: the empty-unsigned quarantine (the reconciler’s
“no captured steps” refusal) does NOT set capture_failed = 1 (it
is a distinct semantic — “no work was captured” rather than
“capture was lost mid-flight”), so !capture_failed() alone
let the sweep pick it up and emit a spurious SESSION_CLOSE
bridge event for a session that had no other events on the
wire. is_empty_unsigned_quarantine() closes that gap.
Sourcepub fn idle_sessions(&self, idle_s: u64) -> Vec<Arc<Session>>
pub fn idle_sessions(&self, idle_s: u64) -> Vec<Arc<Session>>
Sessions idle longer than idle_s (for the sweeper).
Sourcepub fn open_sessions_including_closed(&self) -> Vec<Arc<Session>>
pub fn open_sessions_including_closed(&self) -> Vec<Arc<Session>>
Snapshot every session in the registry — open, closed, or capture-failed. Used by the dashboard to show recent activity including sessions that have just been sealed but not yet evicted.
Sourcepub fn open_sessions(&self) -> Vec<Arc<Session>>
pub fn open_sessions(&self) -> Vec<Arc<Session>>
Snapshot every session still accepting work.
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 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
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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