use crate::control::state::SharedState;
#[derive(Debug, Clone, Copy)]
pub struct AppliedIndexGate {
pub cache_applied: u64,
pub watcher_current: u64,
pub gap: u64,
}
impl AppliedIndexGate {
pub fn is_ok(&self) -> bool {
self.gap == 0
}
}
pub fn check_applied_index(shared: &SharedState) -> AppliedIndexGate {
if shared.cluster_topology.is_none() {
return AppliedIndexGate {
cache_applied: 0,
watcher_current: 0,
gap: 0,
};
}
let cache_applied = {
let cache = match shared.metadata_cache.read() {
Ok(c) => c,
Err(p) => {
tracing::error!(
"metadata_cache RwLock poisoned during applied-index gate — \
recovering guard"
);
p.into_inner()
}
};
cache.applied_index
};
let watcher_current = shared
.applied_index_watcher(nodedb_cluster::METADATA_GROUP_ID)
.current();
let gap = watcher_current.saturating_sub(cache_applied);
AppliedIndexGate {
cache_applied,
watcher_current,
gap,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn gate_ok_when_indexes_match() {
let g = AppliedIndexGate {
cache_applied: 42,
watcher_current: 42,
gap: 0,
};
assert!(g.is_ok());
}
#[test]
fn gate_fails_on_gap() {
let g = AppliedIndexGate {
cache_applied: 10,
watcher_current: 42,
gap: 32,
};
assert!(!g.is_ok());
}
}