use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
pub fn enabled() -> bool {
matches!(std::env::var("TF_RA_IDLE_EVICT").as_deref(), Ok("1"))
}
pub fn idle_window() -> Duration {
const DEFAULT_SECS: u64 = 30;
const FLOOR_SECS: u64 = 5;
let secs = match std::env::var("TF_RA_IDLE_SECS") {
Ok(v) => v
.parse::<u64>()
.map(|n| n.max(FLOOR_SECS))
.unwrap_or(DEFAULT_SECS),
Err(_) => DEFAULT_SECS,
};
Duration::from_secs(secs)
}
#[derive(Debug, Default)]
pub struct IdleEvictCounters {
evictions: AtomicU64,
suspended_ms: AtomicU64,
}
impl IdleEvictCounters {
pub fn new() -> Self {
Self::default()
}
pub fn record_eviction(&self) {
self.evictions.fetch_add(1, Ordering::Relaxed);
}
pub fn add_suspended(&self, d: Duration) {
self.suspended_ms
.fetch_add(d.as_millis() as u64, Ordering::Relaxed);
}
pub fn snapshot(&self) -> (u64, u64) {
(
self.evictions.load(Ordering::Relaxed),
self.suspended_ms.load(Ordering::Relaxed),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn enabled_is_strict_one_default_off() {
fn rule(v: Option<&str>) -> bool {
v == Some("1")
}
assert!(rule(Some("1")));
assert!(!rule(None));
assert!(!rule(Some("")));
assert!(!rule(Some("0")));
assert!(!rule(Some("true")));
}
#[test]
fn idle_window_default_and_clamp_rule() {
fn rule(v: Option<&str>) -> u64 {
const DEFAULT_SECS: u64 = 30;
const FLOOR_SECS: u64 = 5;
match v {
Some(s) => s
.parse::<u64>()
.map(|n| n.max(FLOOR_SECS))
.unwrap_or(DEFAULT_SECS),
None => DEFAULT_SECS,
}
}
assert_eq!(rule(None), 30, "unset ⇒ default");
assert_eq!(rule(Some("garbage")), 30, "non-numeric ⇒ default");
assert_eq!(rule(Some("120")), 120, "sane value honored");
assert_eq!(rule(Some("1")), 5, "below floor ⇒ clamped to 5");
assert_eq!(rule(Some("5")), 5, "floor exact");
}
#[test]
fn counters_track_evictions_and_suspended_time() {
let c = IdleEvictCounters::new();
assert_eq!(c.snapshot(), (0, 0));
c.record_eviction();
c.add_suspended(Duration::from_millis(1500));
c.record_eviction();
c.add_suspended(Duration::from_millis(500));
assert_eq!(c.snapshot(), (2, 2000));
}
}