Skip to main content

LoadedWorkspace

Struct LoadedWorkspace 

Source
pub struct LoadedWorkspace {
Show 14 fields pub key: WorkspaceKey, pub graph: ArcSwap<CodeGraph>, pub state: AtomicU8, pub last_accessed: RwLock<Instant>, pub memory_bytes: AtomicUsize, pub memory_high_water_bytes: AtomicUsize, pub pinned: bool, pub last_error: RwLock<Option<DaemonError>>, pub last_good_at: RwLock<Option<SystemTime>>, pub retry_count: AtomicU32, pub rebuild_lane: Mutex<Option<PendingRebuild>>, pub rebuild_cancelled: AtomicBool, pub rebuild_in_flight: AtomicBool, pub last_indexed_git_state: RwLock<Option<LastIndexedGitState>>,
}
Expand description

Per-workspace runtime state owned by the super::WorkspaceManager::workspaces map.

Mutating state:

  • graph, state, memory_bytes, memory_high_water_bytes, retry_count, rebuild_cancelled are all atomic — queries and status readers can observe them without taking a mutex.
  • last_accessed, last_error, last_good_at are short-critical- section RwLocks — writers are the dispatcher / router at publish/fail time.
  • rebuild_lane is a tokio::sync::Mutex per A2 §J.4; the dispatcher holds it briefly to coalesce pending work.

Construction is expensive only in that ArcSwap::new allocates one Arc<CodeGraph> up front. A fresh workspace is initialised with an empty-but-live CodeGraph; the real graph is installed by the first publish_and_retain.

Fields§

§key: WorkspaceKey

Identity key under which the manager stores this workspace.

Immutable for the lifetime of the workspace; if the config fingerprint or root mode change, the workspace is unloaded under the old key and freshly loaded under a new key.

§graph: ArcSwap<CodeGraph>

Published graph. Readers call graph.load_full().

Only [crate::workspace::publish::publish_and_retain] swaps a new graph in; eviction stores a fresh empty graph so the ArcSwap remains non-null (simpler than Option-wrapping).

§state: AtomicU8

Current lifecycle state. Stored as AtomicU8 to keep the status read path lock-free; round-trip via WorkspaceState::as_u8 / WorkspaceState::from_u8.

§last_accessed: RwLock<Instant>

Last wall-clock time a query observed this workspace, used by LRU eviction (§G.7). Short critical section; RwLock keeps contention negligible.

§memory_bytes: AtomicUsize

Current heap_bytes of the published graph. Updated on every successful publish_and_retain. Reads use Relaxed ordering — the authoritative aggregate lives on super::admission::AdmissionState.

§memory_high_water_bytes: AtomicUsize

Peak memory_bytes observed over this workspace’s loaded lifetime. Per Amendment 2 §D:

High-water marks are monotonic over the workspace’s loaded lifetime — they reset only on unload/eviction (fresh LoadedWorkspace), not on rebuilds or backoff.

Updated via fetch_max alongside every memory_bytes store.

§pinned: bool

Whether LRU eviction must skip this workspace.

§last_error: RwLock<Option<DaemonError>>

Most recent build/load error, if any. None in the WorkspaceState::Loaded steady state. Populated on transition into WorkspaceState::Failed and read back by the router when surfacing meta.last_error on stale responses.

§last_good_at: RwLock<Option<SystemTime>>

Wall-clock of the most recent successful rebuild. Used by the router to compute age_hours for the stale_serve_max_age_hours cap and the JSON-RPC -32002 error error.data.age_hours payload.

§retry_count: AtomicU32

Count of consecutive failed rebuilds. Drives the exponential backoff schedule (§G.7 / plan Step 6: 30s → 60s → 120s → 300s → 600s). Reset to 0 on every successful publish.

§rebuild_lane: Mutex<Option<PendingRebuild>>

At most one queued rebuild per workspace. None when the dispatcher’s lane is idle. Filled / coalesced by the dispatcher (Task 7).

§rebuild_cancelled: AtomicBool

Lock-free cancellation signal for in-flight rebuilds. Set by evict_lru / explicit unload and polled by the rebuild pipeline at each pass boundary. Once set, the running rebuild aborts, drops its RebuildReservation, and never publishes.

§rebuild_in_flight: AtomicBool

Runner-role gate for the per-workspace rebuild serial consumer (A2 §J.2, Task 7 Phase 7b1). When true, exactly one crate::RebuildDispatcher::handle_changes call is actively running the full rebuild pipeline (the Phase B drain loop in rebuild.rs). A concurrent caller observing true under the Self::rebuild_lane lock MUST park its coalesced PendingRebuild in the lane and return Ok(()) without executing — the active runner will drain the lane at its next drain-loop iteration.

§Invariant

All normal-path transitions of this flag happen while Self::rebuild_lane is held. DrainLoopSentinel::drop in rebuild.rs is the sole recovery exception — it stores false without the lane on the unwind path, with the narrow-race semantics documented on that type.

§Authorised modifiers

  • RebuildDispatcher::handle_changes Phase A (false → true under lane).
  • RebuildDispatcher::handle_changes Phase B drain-loop exit (true → false under lane, when the lane is empty or the top-of-loop eviction gate fires).
  • DrainLoopSentinel::drop panic-safety path (true → false, bare atomic store, narrow race).

Nothing in WorkspaceManager (execute_eviction, publish_and_retain, the retention reaper) touches this flag. It is dispatcher-local coordination, independent of the rebuild_cancelled eviction signal.

§last_indexed_git_state: RwLock<Option<LastIndexedGitState>>

Git state that the currently-published graph was indexed against (Task 7 Phase 7b2, A2 §I / §J.2).

Read by the per-workspace watcher bridge as the last_git_state argument to sqry_core::watch::SourceTreeWatcher::wait_for_changes_cancellable so the classifier has a valid baseline on every debounce window.

Advanced ONLY by crate::RebuildDispatcher::execute_one_rebuild after crate::WorkspaceManager::publish_and_retain succeeds, using the git_state_at_enqueue snapshot attached to the PendingRebuild that produced the publish. A failed rebuild MUST leave this field unchanged so the next wait_for_changes_cancellable call still sees the divergent state and retries.

§Invariant

  • Only execute_one_rebuild’s successful-publish arm writes this field.
  • Watcher-side event receipt, cancellation, or rebuild failure never write this field.
  • The write happens under parking_lot::RwLock — short critical section, no cross-lock ordering concerns.

None on workspace construction (no rebuild has published yet). The first successful execute_one_rebuild driven by the watcher bridge (which attaches git_state_at_enqueue = Some(...)) populates this field.

Implementations§

Source§

impl LoadedWorkspace

Source

pub fn new(key: WorkspaceKey, pinned: bool) -> Self

Construct a fresh workspace entry with an empty initial graph.

The empty graph is Arc-cheap (sub-kilobyte) so keeping the ArcSwap non-null for the entire workspace lifetime avoids an Option layer on the query path. Eviction stores another empty graph through the same ArcSwap; re-load overwrites it.

Source

pub fn load_state(&self) -> WorkspaceState

Atomic state read. Round-trips through WorkspaceState::from_u8; a discriminant outside the current range panics (it is a telemetry-corruption bug, not a recoverable condition).

Source

pub fn store_state(&self, new_state: WorkspaceState)

Atomic state write.

Source

pub fn update_memory(&self, new_bytes: usize) -> usize

Update memory_bytes and keep memory_high_water_bytes monotonic. Matches Amendment 2 §D:

Every time memory_bytes is assigned (initial load, full rebuild completion, incremental rebuild’s ArcSwap::store), immediately call memory_high_water_bytes.fetch_max(new, Relaxed).

Returns the previous memory_bytes value so the caller can compute the delta the admission accounting needs.

Source

pub fn touch(&self)

Stamp last_accessed = now on a query. Held under an RwLock so the query hot path never blocks — writers contend only with other writers.

Source

pub fn record_success(&self, at: SystemTime)

Record a successful build’s wall-clock + reset retry counter.

Source

pub fn record_failure(&self, err: DaemonError) -> u32

Record a failed build and return the new retry count. The dispatcher uses this to pick the exponential-backoff schedule.

Trait Implementations§

Source§

impl Debug for LoadedWorkspace

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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