use std::time::Duration;
#[cfg(doc)]
use super::{CheckpointSeverityState, SessionSweepConfig};
pub const DEFAULT_WARN_SUSTAINED_CYCLES: u8 = 3;
#[derive(Clone, Debug)]
pub struct CheckpointConfig {
pub interval: Duration,
pub warn_pages: u64,
pub warn_sustained_cycles: u8,
pub high_water_pages: u64,
pub truncate_high_water_pages: u64,
pub truncate_min_interval: Duration,
pub truncate_busy_timeout: Duration,
pub tx_warn_secs: Duration,
pub tx_max_age_secs: Duration,
}
impl Default for CheckpointConfig {
fn default() -> Self {
Self {
interval: Duration::from_millis(500),
warn_pages: 2000,
warn_sustained_cycles: DEFAULT_WARN_SUSTAINED_CYCLES,
high_water_pages: 6000,
truncate_high_water_pages: 20_000,
truncate_min_interval: Duration::from_secs(300),
truncate_busy_timeout: Duration::from_millis(2000),
tx_warn_secs: Duration::from_secs(30),
tx_max_age_secs: Duration::from_secs(120),
}
}
}
impl CheckpointConfig {
pub fn from_env() -> Self {
let mut cfg = Self::default();
let n = crate::env::env_parse_or("KHIVE_CHECKPOINT_INTERVAL_MS", 0_u64);
if n > 0 {
cfg.interval = Duration::from_millis(n);
}
let n = crate::env::env_parse_or("KHIVE_WAL_WARN_PAGES", 0_u64);
if n > 0 {
cfg.warn_pages = n;
}
let n = crate::env::env_parse_or("KHIVE_WAL_WARN_SUSTAINED_CYCLES", 0_u8);
if n > 0 {
cfg.warn_sustained_cycles = n;
}
let n = crate::env::env_parse_or("KHIVE_WAL_HIGH_WATER_PAGES", 0_u64);
if n > 0 {
cfg.high_water_pages = n;
}
let n = crate::env::env_parse_or("KHIVE_WAL_TRUNCATE_HIGH_WATER_PAGES", 0_u64);
if n > 0 {
cfg.truncate_high_water_pages = n;
}
let n = crate::env::env_parse_or("KHIVE_WAL_TRUNCATE_MIN_INTERVAL_SECS", 0_u64);
if n > 0 {
cfg.truncate_min_interval = Duration::from_secs(n);
}
let n = crate::env::env_parse_or("KHIVE_WAL_TRUNCATE_BUSY_MS", 0_u64);
if n > 0 {
cfg.truncate_busy_timeout = Duration::from_millis(n);
}
(cfg.tx_warn_secs, cfg.tx_max_age_secs) =
tx_age_thresholds_from_env(cfg.tx_warn_secs, cfg.tx_max_age_secs);
cfg
}
}
pub(crate) fn tx_age_thresholds_from_env(
default_warn: Duration,
default_max: Duration,
) -> (Duration, Duration) {
let mut warn_secs = default_warn;
let mut max_age_secs = default_max;
let n = crate::env::env_parse_or("KHIVE_TX_WARN_SECS", 0_u64);
if n > 0 {
warn_secs = Duration::from_secs(n);
}
let n = crate::env::env_parse_or("KHIVE_TX_MAX_AGE_SECS", 0_u64);
if n > 0 {
max_age_secs = Duration::from_secs(n);
}
if warn_secs >= max_age_secs {
tracing::warn!(
configured_tx_warn_secs = warn_secs.as_secs_f64(),
configured_tx_max_age_secs = max_age_secs.as_secs_f64(),
fallback_tx_warn_secs = default_warn.as_secs_f64(),
fallback_tx_max_age_secs = default_max.as_secs_f64(),
"KHIVE_TX_WARN_SECS must be strictly less than KHIVE_TX_MAX_AGE_SECS; \
both transaction-age thresholds were rejected and reset to their defaults"
);
return (default_warn, default_max);
}
(warn_secs, max_age_secs)
}