pub struct MemWatchdog { /* private fields */ }Expand description
The watchdog: a meminfo path, a floor, and the counters that say what it did.
Implementations§
Source§impl MemWatchdog
impl MemWatchdog
Sourcepub fn with(meminfo: &Path, budget: u64, poll: Duration) -> Self
pub fn with(meminfo: &Path, budget: u64, poll: Duration) -> Self
An explicit watchdog: meminfo is what is read, budget the floor in
bytes, poll the re-check cadence. What a test builds.
Sourcepub fn bounded(self, resume_margin: u64, deadline: Duration) -> Self
pub fn bounded(self, resume_margin: u64, deadline: Duration) -> Self
The two bounds that make a pause end: the absolute resume margin and the
deadline. Duration::ZERO disables the deadline — the pre-2026-08-30
shape, which only a test asks for.
Sourcepub fn with_reflush(self, every: Duration) -> Self
pub fn with_reflush(self, every: Duration) -> Self
How often the flush runs again during one pause. A test shortens it so
that the empty-flush arm can be asserted without 20 s of wall clock;
production leaves it at REFLUSH_EVERY.
pub fn budget(&self) -> u64
pub fn total(&self) -> u64
Sourcepub fn available(&self) -> Option<u64>
pub fn available(&self) -> Option<u64>
MemAvailable right now, or None if the file cannot be read — and
None never pauses: a box with no /proc is not a box short of memory.
Sourcepub fn breached(&self) -> Option<(u64, u64)>
pub fn breached(&self) -> Option<(u64, u64)>
Some((available, budget)) when the floor is breached.
Sourcepub fn resume_margin(&self) -> u64
pub fn resume_margin(&self) -> u64
The absolute resume margin this watchdog uses — RESUME_MARGIN_BYTES,
or ZNIPPY_GIT_MEM_RESUME_MARGIN_BYTES. Never more than the floor
itself: a margin bigger than the budget would be the old bug in a new
spelling.
Sourcepub fn pause_deadline(&self) -> Duration
pub fn pause_deadline(&self) -> Duration
The ceiling on one pause — PAUSE_DEADLINE, or
ZNIPPY_GIT_MEM_PAUSE_MAX_MS. 0 means “no deadline”, which is what a
test asks for when it wants the old shape on purpose.
Sourcepub fn pause_until_ok(
&self,
label: &str,
cancel: Option<&AtomicBool>,
flush: &mut dyn FnMut() -> Result<u64>,
) -> Result<Pause>
pub fn pause_until_ok( &self, label: &str, cancel: Option<&AtomicBool>, flush: &mut dyn FnMut() -> Result<u64>, ) -> Result<Pause>
The check. Returns immediately when the floor holds. Otherwise runs
flush (the caller drops what it can, and says how much it dropped),
then waits — re-reading every poll, re-flushing every
REFLUSH_EVERY — until one of the four things in PauseEnd
happens.
flush returns what it freed: rows, bytes, entries, whatever the
caller counts — the number is only ever compared with zero. Three zeros
in a row (GIVE_UP_AFTER_EMPTY_FLUSHES) with memory no better than it
started means there is nothing on this box left to give, and the wait
ends with PauseEnd::NothingToGive instead of continuing. So does
MemWatchdog::pause_deadline expiring.
A pause that cannot end is worse than a pack that is refused, which is the whole lesson of lane P2’s two rig boxes: they parked for 31m44s and 1h45m41s, emitted 190 and 627 spills that freed nothing, and never resumed. The caller decides what to do with a give-up; this decides that there IS one.
label names the worker in the log lines (alice/linux).