Skip to main content

SweepScope

Enum SweepScope 

Source
pub enum SweepScope<'a> {
    Boot,
    Live(&'a HashSet<String>),
}
Expand description

Delete session snapshots (and their journals) beyond the retention caps.

Nothing pruned this directory before car#1310, so <id>.json and the larger <id>.events.jsonl beside it accumulated for the life of the installation — and coder.list pays a read, a serde_json parse and a stat for every one of them on every call. car#1262 bounded the in-memory registry and explicitly left this alone; this is the disk arm.

Two exemptions, both about not destroying the only record of something that still exists:

  • A session that is not terminal is never collected. Same rule as RunStore’s in-progress exemption. Note this covers NeedsApproval, which is deliberately non-terminal — a snapshot waiting on a human is not garbage however old it is.
  • A session whose workspace_path is still a directory is never collected. The snapshot is the only thing that names that worktree; deleting it turns a directory an operator kept (keep_workspace_on_failure) or a preserved needs_approval orphan into an unattributable leak.

The count cap ranks only COLLECTABLE sessions, matching RunStore’s completed_rank: an exempt session neither dies nor consumes a keeper slot. So max_sessions is a bound on what retention manages, NOT on the size of the directory — an install that sets keep_workspace_on_failure holds every failed session’s snapshot, journal AND worktree on top of the cap, by the operator’s own request. Restart-orphaned worktrees are also retained: a crash must not erase unfinished edits merely to satisfy history caps. Once a retained worktree is explicitly removed, its history is collectable.

The age cap reads updated_at, which is stamped on every transition, so it measures time since the session last did anything rather than since it started.

The journal is unlinked BEFORE the snapshot, and the collection is counted on the snapshot. Only *.json is enumerated, so a journal whose snapshot is already gone is invisible to the candidate pass — removing the snapshot first would strand the larger file permanently on any unlink error. (The pass at the end sweeps journals already stranded that way, including by a coder.start that created the sink and died before its first persist.)

Best-effort: an unreadable snapshot is skipped, and a failed unlink is logged rather than propagated — this runs at boot and must not block it. Returns the number of sessions collected. Which process state a gc_sessions sweep is running in.

Not an Option<&HashSet>: that carries two orthogonal bits in one type and only one of them is about the set. None would have to mean BOTH “filter nothing” AND “sweep orphan journals” — so a caller with no live set to hand over, the natural reading of None, would silently re-enable a deletion pass that is safe only where no live sink can own a journal.

Variants§

§

Boot

Daemon construction, where the session registry is provably empty. Also sweeps orphan journals, which is safe only here.

§

Live(&'a HashSet<String>)

Mid-lifetime, carrying the ids the in-process registry still holds.

Auto Trait Implementations§

§

impl<'a> Freeze for SweepScope<'a>

§

impl<'a> RefUnwindSafe for SweepScope<'a>

§

impl<'a> Send for SweepScope<'a>

§

impl<'a> Sync for SweepScope<'a>

§

impl<'a> Unpin for SweepScope<'a>

§

impl<'a> UnsafeUnpin for SweepScope<'a>

§

impl<'a> UnwindSafe for SweepScope<'a>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

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<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

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> 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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

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