pub struct SessionsRegistry { /* private fields */ }Expand description
The cross-window session registry.
The in-memory, TTL-reaped set of running Claude sessions plus the companion
window-embedding reports used to tag a session’s Source. Hosted by
SessionsService.
Implementations§
Source§impl SessionsRegistry
impl SessionsRegistry
Sourcepub fn delivery(&self) -> DeliveryStats
pub fn delivery(&self) -> DeliveryStats
How events have reached the registry since it was created (#2136).
Sourcepub fn subscribe_changes(&self) -> Receiver<u64>
pub fn subscribe_changes(&self) -> Receiver<u64>
A change-notification receiver for the push subscription: it observes a
new value each time the rendered session state changes (see
bump). Created with the current version already marked
seen, so the first watch::Receiver::changed resolves on the next
change — the subscriber sends its own initial snapshot up front and then
waits for deltas (#1414).
Sourcepub fn observe(&self, req: ObserveRequest)
pub fn observe(&self, req: ObserveRequest)
Records (upserts) a session sighting, running the SessionState
inference and refreshing liveness. Reaps stale entries first, then — only
when a genuinely new session would grow the map past [MAX_SESSIONS] —
evicts the longest-silent entry. Infallible: an upsert never evicts.
Best-effort fields (cwd/transcript_path/repo/model) fill in on
an existing entry and never overwrite known data with None, so a later
hook enriches a watcher-discovered session without a race losing data.
bumps only when the sighting changed something a consumer
renders — a brand-new session, a SessionState transition, a
best-effort field taking a new value, or a reap that dropped a sibling.
A repeat sighting that merely refreshes liveness does not, since hooks
fire on every tool call (the heartbeat precedent in
WorktreesRegistry).
For the daemon’s own in-process feeds: it is the Local origin, which
DeliveryStats does not count. The control socket’s feed goes through
observe_stamped as the Socket origin.
Sourcepub fn end(
&self,
session_id: &str,
reason: Option<&str>,
pid: Option<u32>,
) -> bool
pub fn end( &self, session_id: &str, reason: Option<&str>, pid: Option<u32>, ) -> bool
Marks a session ended (SessionEnd), so list shows it as ended for a
short window ([ENDED_SESSION_TTL]) before it is reaped. Returns whether
the session was known. A no-op for an already-unknown session (a
duplicate/late SessionEnd).
Also a no-op when pid is a process the session was taken over from:
an in-place resume (a VS Code window reload) starts a new process on the
same session_id without waiting for the old one to exit, so the old
process’s SessionEnd can arrive after the new one’s SessionStart
(#1948). Any other end — no pid, the owning pid, or a pid never seen
(a wrapped hook command whose parent is a per-hook shell) — ends the
session, so the rule can only ever keep a session the old process no
longer owns.
For the daemon’s own in-process feeds, as observe is
(the Local origin).
Sourcepub fn report_window(&self, report: WindowReport)
pub fn report_window(&self, report: WindowReport)
Records (upserts) a companion window-embedding report and refreshes its
liveness. Reaps stale windows first, then caps like observe.
bumps only when the report changes the Source join a
consumer renders — a new window, different folders, or an embedding that
appeared or vanished — never on the unchanged ~10 s refresh every open
window sends, which would otherwise put a permanent push floor under the
daemon proportional to the window count.
Sourcepub fn unregister_window(&self, key: &str) -> bool
pub fn unregister_window(&self, key: &str) -> bool
Drops a companion window-embedding report (the window closed). Returns whether an entry was present.
Sourcepub fn credit_window_outage(&self, outage: Duration)
pub fn credit_window_outage(&self, outage: Duration)
Pauses the window-report liveness clock for outage: advances every live
report’s last_active by that long, never past now (#2111).
For a stretch when the daemon could not accept connections, so no window’s
~10 s refresh could arrive. Without this the first window op after the
outage reaps every other report that has been quiet more than the 30 s TTL,
and the sessions in those windows flip from vscode to terminal until each
window reports again — the same failure
WorktreesRegistry::credit_outage fixes for the window registry.
outage is measured on a monotonic Instant, the
same awake time as the [AwakeClock] the reports are stamped on, so the
two compose: the credit shifts a stamp by time the daemon was awake but
deaf, and a system sleep still ages nothing (#2108).
Only window reports are credited. A session’s own last_active is not: a
live one has a five-minute TTL that an outage rarely approaches, and an
ended one’s short linger is not worth stretching. Not a visible change, so
it does not bump the change-notify.
Sourcepub fn list(&self) -> Vec<SessionEntry>
pub fn list(&self) -> Vec<SessionEntry>
Reaps stale sessions and windows, then returns the live sessions with
each Source resolved and sorted for deterministic output.
Two independent locks, each held only for pure-CPU work and never
nested: the sessions snapshot is taken and the lock dropped, then the
windows snapshot, then the join runs lock-free. Path matching is a pure
prefix compare (no canonicalization / disk I/O), honouring the
Mutex-never-across-.await and no-I/O-under-lock invariants.
Deliberately does not bump, even when its inline reap
drops an entry: this is the body of every subscription’s snapshot(), so
bumping here would feed the stream loop back into itself. A read-path reap
reaches other subscribers on the server’s next periodic re-sample, whose
diff sees the shrunken list — the WorktreesRegistry::list arrangement.
Sourcepub fn focus_folder(&self, session_id: &str) -> Option<PathBuf>
pub fn focus_folder(&self, session_id: &str) -> Option<PathBuf>
The first workspace folder of the still-live window a session is embedded
in, if any — used by the tray “focus” action to resolve a session to a
folder to open in VS Code. None when the session has no cwd, or is not
matched to a reporting window with a folder.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for SessionsRegistry
impl !RefUnwindSafe for SessionsRegistry
impl !UnwindSafe for SessionsRegistry
impl Send for SessionsRegistry
impl Sync for SessionsRegistry
impl Unpin for SessionsRegistry
impl UnsafeUnpin for SessionsRegistry
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