Skip to main content

WorktreesRegistry

Struct WorktreesRegistry 

Source
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

Source

pub fn new() -> Self

Creates the registry with the default liveness TTL. Cheap — no I/O.

Source

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).

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn unregister(&self, key: &str) -> bool

Drops a window’s registration. Returns whether an entry was present.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn pushing_paths(&self) -> HashSet<PathBuf>

The worktree paths currently being pushed, canonicalized (#1443). The rebasing_paths twin, read into the same snapshot.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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).

Source

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§

Source§

impl Default for WorktreesRegistry

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more