pub struct WorktreesRegistry { /* private fields */ }Expand description
The cross-window worktree registry: the in-memory, TTL-reaped set of open
windows. Hosted by
WorktreesService.
Implementations§
Source§impl WorktreesRegistry
impl WorktreesRegistry
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 visible window set changes (see changes and
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 (#1267).
Sourcepub fn change_generation(&self) -> u64
pub fn change_generation(&self) -> u64
The current change-notify generation — the counter bump
increments on every visible-set change. Read (never subscribed) so a
coalescing consumer — the service’s shared tree-snapshot cache (#1303) —
can tell whether the registry has changed since it last computed and
rebuild only then. The value itself is immaterial; only whether it
differs between two reads matters, so wrapping_add overflow is benign.
Sourcepub fn register(&self, req: RegisterRequest)
pub fn register(&self, req: RegisterRequest)
Records (upserts) a window registration. Reaps stale entries first, then
— only when a genuinely new key would grow the map past [MAX_WINDOWS] —
evicts the longest-silent entry. Infallible: an upsert never evicts, and
callers validate the key before reaching here.
Sourcepub fn credit_outage(&self, outage: Duration)
pub fn credit_outage(&self, outage: Duration)
Pauses the liveness clock for outage: advances every live entry’s
last_active (and its display last_seen) by that long, never past now.
For a stretch when the daemon could not hear its windows — its accept
loop was failing (#2111) — so their silence says nothing about whether they
are alive. Without this the first heartbeat after an outage reaps every
other window that has been quiet more than the TTL, before it has had a
chance to send its own, and whole repos vanish from the tree for a few
seconds. Only entries still in the map are credited: an entry that was
already reaped stays gone, and one that was already stale before the outage
began is credited no more than its neighbours. Not a visible change, so it
does not bump the change-notify.
outage is measured on a monotonic Instant, the
same awake time as the AwakeClock the entries 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 (#2126).
Sourcepub fn heartbeat(&self, key: &str) -> bool
pub fn heartbeat(&self, key: &str) -> bool
Refreshes a window’s liveness. Returns whether the key was known: a
false tells a window that started before the daemon — or survived a
daemon restart — to re-register, since the registry is in-memory and
has no record of it.
Sourcepub fn unregister(&self, key: &str) -> bool
pub fn unregister(&self, key: &str) -> bool
Drops a window’s registration. Returns whether an entry was present.
Sourcepub fn mark_close_pending(&self, key: &str)
pub fn mark_close_pending(&self, key: &str)
Records a pending “close yourself” directive for key, to be surfaced on
that window’s next heartbeat. Set by the close op when signalling a
window it can only reply to. Idempotent; infallible.
Sourcepub fn take_close_pending(&self, key: &str) -> bool
pub fn take_close_pending(&self, key: &str) -> bool
Takes (returns and clears) key’s pending close directive. Called on
each heartbeat so the directive fires exactly once; a false means no
close is pending.
Sourcepub fn cancel_close_pending(&self, key: &str) -> bool
pub fn cancel_close_pending(&self, key: &str) -> bool
Withdraws key’s pending close directive without delivering it (#2139):
the close op’s counterpart to mark_close_pending,
called when its wait fails so a directive it set cannot outlive an op the
caller was told had failed. Without it a timed-out close reports failure
while the window closes itself on its next heartbeat.
Returns whether the directive was still pending. A false means the
window already took it (it is closing, only slowly — a delivered
directive cannot be recalled) or it was cleared by an unregister.
The set holds a key once, not a count, so two concurrent closes whose targets share a multi-root window share one entry: whichever gives up first withdraws it for both. The ops are fanned out together, so the other loses at most the skew between their starts, and only if the window comes back inside it after being unresponsive for the whole of the first’s wait. That is not worth a per-op ticket.
Sourcepub fn mark_reload_pending(&self, key: &str)
pub fn mark_reload_pending(&self, key: &str)
Records a pending “reload yourself” directive for key, to be surfaced
on that window’s next heartbeat (#1417). Set by the reload op for
every target window, which — unlike a close — includes no waiting: the
caller learns only that the directive was marked. Idempotent; infallible.
Sourcepub fn take_reload_pending(&self, key: &str) -> bool
pub fn take_reload_pending(&self, key: &str) -> bool
Takes (returns and clears) key’s pending reload directive. Called on
each heartbeat so the directive fires exactly once; a false means no
reload is pending.
Sourcepub fn mark_rebasing(&self, paths: &[PathBuf]) -> bool
pub fn mark_rebasing(&self, paths: &[PathBuf]) -> bool
Marks paths as being rebased right now (#1415), returning whether the
set actually changed.
A real change bumps the change-notify so every subscribed
window re-pushes a snapshot carrying the spinner — the same cross-window
sync set_show_closed / set_polling rely on. Bumping only on a real
change is load-bearing rather than an optimization: an unconditional bump
defeats the server’s snapshot diff and re-pushes to every window on every
tick.
Callers pass already-canonicalized paths, so these match the tree
snapshot’s own keys. Canonicalizing is disk I/O, which belongs in the
adapter (where canonical() lives), not in this engine — the same split
that keeps the git enrichment out of here.
Sourcepub fn clear_rebasing(&self, paths: &[PathBuf]) -> bool
pub fn clear_rebasing(&self, paths: &[PathBuf]) -> bool
Clears the rebasing mark on paths, returning whether the set changed.
Called on every exit from a phase-2 execute, so a panicking or failing
rebase can never leave a permanent spinner on a row.
Sourcepub fn mark_pushing(&self, paths: &[PathBuf]) -> bool
pub fn mark_pushing(&self, paths: &[PathBuf]) -> bool
Marks paths as being pushed right now (#1443), returning whether the set
actually changed. The mark_rebasing twin, with the
same canonicalized-paths-in and bump-only-on-a-real-change contract.
Sourcepub fn clear_pushing(&self, paths: &[PathBuf]) -> bool
pub fn clear_pushing(&self, paths: &[PathBuf]) -> bool
Clears the pushing mark on paths, returning whether the set changed.
Called on every exit from a phase-2 execute — and it is the only thing
that clears this cue, since a push leaves no on-disk state a later snapshot
could correct a stale mark from.
Sourcepub fn rebasing_paths(&self) -> HashSet<PathBuf>
pub fn rebasing_paths(&self) -> HashSet<PathBuf>
The worktree paths currently being rebased, canonicalized. Read into each
tree/subscribe snapshot; cheap (a set clone of at most a batch’s worth
of paths) and never held across an .await.
Sourcepub fn pushing_paths(&self) -> HashSet<PathBuf>
pub fn pushing_paths(&self) -> HashSet<PathBuf>
The worktree paths currently being pushed, canonicalized (#1443). The
rebasing_paths twin, read into the same snapshot.
Sourcepub fn show_closed(&self) -> bool
pub fn show_closed(&self) -> bool
The current show/hide-closed toggle: whether the tree view shows
worktrees with no open window (#1301). Read into every tree/subscribe
snapshot so every window renders the same, live-synced state.
Sourcepub fn set_show_closed(&self, show_closed: bool) -> bool
pub fn set_show_closed(&self, show_closed: bool) -> bool
Sets the show/hide-closed toggle, returning whether the value actually
changed. A real change bumps the change-notify so every
subscriber re-pushes a snapshot carrying the new value — the reliable
cross-window sync context.globalState could not provide. A no-op set
(same value) neither bumps nor wakes anyone.
Sourcepub fn is_polling_enabled(&self, owner: &str, name: &str) -> bool
pub fn is_polling_enabled(&self, owner: &str, name: &str) -> bool
Whether PR polling is currently leased for the GitHub repo owner/name
(#1376) — the entry exists and its lease has not expired. Defaults
false (a never-toggled repo does not poll), so only repos the user has
explicitly enabled, within the last poll_ttl, poll.
Sourcepub fn enabled_polling_repos(&self) -> HashSet<String>
pub fn enabled_polling_repos(&self) -> HashSet<String>
The repos with a live (unexpired) lease, as a set of "owner/name"
keys — what stamps polling_enabled onto the tree snapshot. Reaps
expired leases first (the window-TTL reap-on-read precedent), so an idle
repo drops out on the next snapshot build without a background timer.
Cloned out so the lock is never held across the (blocking-thread) tree
build that reads it.
Sourcepub fn polling_snapshot(&self) -> Vec<(String, DateTime<Utc>)>
pub fn polling_snapshot(&self) -> Vec<(String, DateTime<Utc>)>
The live leases as (repo, expiry) pairs sorted by repo, for
deterministic persistence to the 0600 prefs file (#1376) — the expiry is
stored so a daemon restart within the lease window keeps the remaining
time rather than resetting the clock. Reaps expired leases first, so a
stale entry is never written back.
Sourcepub fn set_polling(&self, owner: &str, name: &str, enabled: bool) -> bool
pub fn set_polling(&self, owner: &str, name: &str, enabled: bool) -> bool
Enables (leases for poll_ttl) or disables PR polling
for owner/name, returning whether the stored map changed — which the
adapter uses to decide whether to persist. Enabling an already-leased repo
refreshes the lease (a new expiry), which is a change worth persisting.
bumps the change-notify only when the repo’s effective
enabled state flips (off→on or on→off), so every subscribed window
re-pushes a snapshot that recolours the icon and drops/keeps badges — the
set_show_closed precedent. A lease refresh
(already on, still on) changes the expiry but not the visible state, so it
persists without waking anyone.
Sourcepub fn seed_polling(
&self,
leases: impl IntoIterator<Item = (String, DateTime<Utc>)>,
)
pub fn seed_polling( &self, leases: impl IntoIterator<Item = (String, DateTime<Utc>)>, )
Replaces the lease map wholesale from the persisted 0600 prefs file
(#1376), dropping any lease that already expired while the daemon was down.
Does not bump: it runs before any window subscribes, so
there is no one to notify, and each window’s first snapshot already
reflects the seeded leases.
Sourcepub fn list(&self) -> Vec<WindowEntry>
pub fn list(&self) -> Vec<WindowEntry>
Reaps stale entries, then returns the live set sorted for deterministic output. Holds the lock only for pure-CPU work.
Like the other reads (open_folders,
first_folder) this reaps but never
bumps: the only observer of a read-path reap is the push
subscription’s own re-snapshot (or status/menu), and the
subscription’s periodic tick already re-samples read-only staleness — so
bumping here would only make the subscription wake itself (#1267).
Sourcepub fn first_folder(&self, key: &str) -> Option<PathBuf>
pub fn first_folder(&self, key: &str) -> Option<PathBuf>
The first workspace folder of a still-live window, if it has one. Used by
the tray “focus” action to resolve a key to a folder to open. Does not
reap — a menu action races the reaper either way, and the caller handles
a None (the window may have closed).
Sourcepub fn open_folders(&self) -> Vec<PathBuf>
pub fn open_folders(&self) -> Vec<PathBuf>
Snapshots the distinct workspace folders across all live windows — the seed set the adapter resolves to repositories (each folder → its git common dir → repo root) to enumerate every worktree per repo (#1265).
Reaps stale entries first, then returns the folders sorted and
deduplicated. Like list it is pure CPU under the lock:
the git resolution the “distinct repos” derivation needs is disk I/O and
stays in the adapter, off the registry lock, honouring the
Mutex-never-across-.await invariant.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for WorktreesRegistry
impl !RefUnwindSafe for WorktreesRegistry
impl !UnwindSafe for WorktreesRegistry
impl Send for WorktreesRegistry
impl Sync for WorktreesRegistry
impl Unpin for WorktreesRegistry
impl UnsafeUnpin for WorktreesRegistry
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