#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct AaePeerStatus {
pub peer_idx: u32,
pub dc: String,
pub rack: String,
pub last_exchange_unix: u64,
pub divergent_keys_since_last_full_sweep: u64,
pub repair_dispatched_total: u64,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct AaeStatusSnapshot {
pub peers: Vec<AaePeerStatus>,
pub snapshot_path: String,
pub snapshot_last_save_unix: u64,
pub snapshot_last_load_unix: u64,
pub snapshot_save_total: u64,
pub snapshot_load_total: u64,
pub snapshot_corruption_total: u64,
pub tree_n_time_buckets: u32,
pub tree_n_segments: u32,
pub tree_time_window_seconds: u64,
pub tree_memory_estimate_bytes: u64,
}
pub trait AaeStatusProvider: Send + Sync {
fn current_status(&self) -> AaeStatusSnapshot;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct NoopAaeStatusProvider;
impl AaeStatusProvider for NoopAaeStatusProvider {
fn current_status(&self) -> AaeStatusSnapshot {
AaeStatusSnapshot::default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn noop_provider_returns_empty_snapshot() {
let p = NoopAaeStatusProvider;
let s = p.current_status();
assert!(s.peers.is_empty());
assert_eq!(s.snapshot_save_total, 0);
assert_eq!(s.tree_n_time_buckets, 0);
}
#[test]
fn snapshot_default_is_empty() {
let s = AaeStatusSnapshot::default();
assert_eq!(s.peers.len(), 0);
assert_eq!(s.snapshot_path, "");
assert_eq!(s.tree_memory_estimate_bytes, 0);
}
#[test]
fn populated_snapshot_carries_per_peer_rows() {
let s = AaeStatusSnapshot {
peers: vec![AaePeerStatus {
peer_idx: 7,
dc: "dc1".into(),
rack: "rA".into(),
last_exchange_unix: 100,
divergent_keys_since_last_full_sweep: 3,
repair_dispatched_total: 2,
}],
snapshot_path: "/var/lib/dynomite/aae/tree.snapshot".into(),
snapshot_last_save_unix: 200,
snapshot_save_total: 5,
..Default::default()
};
assert_eq!(s.peers[0].peer_idx, 7);
assert_eq!(s.snapshot_save_total, 5);
}
}