pub struct RetentionConfig { /* private fields */ }Expand description
Retention policy for the run store (R6). Defaults are the restrictive
50-per-agent / 30-day caps; ~/.car/config.toml [runs] overrides.
A non-positive cap is DISABLED, not zero-tolerance (car#1338). This used
to be read literally, and the literal reading is destructive in the one
direction nobody intends: max_per_agent = 0 made completed_rank >= 0
always true and max_age_days = 0 put the cutoff at now, so either value
deleted every collectable run trace on the next boot, unrecoverably.
An operator writing 0 means “no cap” — that is what it means for
max_session_wall_secs, and for the coder’s own max_sessions /
max_session_age_days in the neighbouring ~/.car/coder.toml. Two
similarly-named retention knobs in one daemon whose zero values inverted was
a hazard whose failure mode was silent data loss, so the two now agree.
This is a choice, not an unqualified convention: CoderConfig’s
max_check_timeout_secs and approval_patch_bytes read 0 as UNSET and
fall back to their defaults, because zero would floor a check at one second
or blind the approval surface. That treatment is the other candidate fix for
this bug and it was rejected on the merits — “unset” restores 50/30, which
still deletes, so it does not close the data loss. 0 is a legal value with
an ambiguous meaning and this defines it; a value that could not have been
intended (a negative or unrepresentable age) is a different case and is
warned about at load.
The fields are PRIVATE and the caps are read as Options, so “disabled” is
a state this type carries rather than a sentinel every call site has to
remember. That is not decoration: the bug was a bare rank >= cap
comparison, and leaving the raw values public would let the next one be
written with no compiler complaint.
Implementations§
Source§impl RetentionConfig
impl RetentionConfig
Sourcepub fn new(max_per_agent: usize, max_age_days: i64) -> Self
pub fn new(max_per_agent: usize, max_age_days: i64) -> Self
Build a policy. 0 (or a negative age) disables that cap — see the
type’s note.
Sourcepub fn age_cap_days(&self) -> Option<i64>
pub fn age_cap_days(&self) -> Option<i64>
The age cap in days, or None when disabled — including when the
configured value cannot be turned into a cutoff at all.
Source§impl RetentionConfig
impl RetentionConfig
Sourcepub fn from_car_dir(car_dir: &Path) -> Self
pub fn from_car_dir(car_dir: &Path) -> Self
Load the retention policy from <car_dir>/config.toml’s [runs]
section, falling back to the restrictive default for any missing
key or an unreadable/malformed file (config errors must never make
the daemon refuse to start — same posture as the rest of .car).
A present key is taken as written, 0 included — see the type’s note on
what 0 means. Filtering it here would silently restore the default
instead of honoring “keep everything”.
Trait Implementations§
Source§impl Clone for RetentionConfig
impl Clone for RetentionConfig
impl Copy for RetentionConfig
Source§impl Debug for RetentionConfig
impl Debug for RetentionConfig
Auto Trait Implementations§
impl Freeze for RetentionConfig
impl RefUnwindSafe for RetentionConfig
impl Send for RetentionConfig
impl Sync for RetentionConfig
impl Unpin for RetentionConfig
impl UnsafeUnpin for RetentionConfig
impl UnwindSafe for RetentionConfig
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
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