use std::time::Duration;
use serde::{Deserialize, Serialize};
pub const CACHE_GRACE_ENV: &str = "BASEMIND_CACHE_GRACE_MINUTES";
const DEFAULT_CACHE_GRACE_MINUTES: u64 = 6 * 60;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ProtectionReason {
Locked,
MostRecentlyUsed,
RecentlyBuilt,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
pub struct ProtectedWorkspace {
pub key: String,
pub root: Option<String>,
pub bytes: u64,
pub reason: ProtectionReason,
}
pub fn cache_grace() -> Duration {
let minutes = match std::env::var(CACHE_GRACE_ENV) {
Ok(raw) => raw.trim().parse::<u64>().unwrap_or_else(|_| {
tracing::warn!(value = %raw, "{CACHE_GRACE_ENV} is not a number; using the default grace window");
DEFAULT_CACHE_GRACE_MINUTES
}),
Err(_) => DEFAULT_CACHE_GRACE_MINUTES,
};
Duration::from_secs(minutes * 60)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn grace_env_parses_default_zero_and_garbage() {
unsafe { std::env::remove_var(CACHE_GRACE_ENV) };
assert_eq!(cache_grace(), Duration::from_secs(6 * 3600));
unsafe { std::env::set_var(CACHE_GRACE_ENV, "0") };
assert_eq!(cache_grace(), Duration::ZERO, "0 disables the window");
unsafe { std::env::set_var(CACHE_GRACE_ENV, "30") };
assert_eq!(cache_grace(), Duration::from_secs(30 * 60));
unsafe { std::env::set_var(CACHE_GRACE_ENV, "soon") };
assert_eq!(
cache_grace(),
Duration::from_secs(6 * 3600),
"garbage keeps the default"
);
unsafe { std::env::remove_var(CACHE_GRACE_ENV) };
}
}