Skip to main content

fresh/services/
counters.rs

1//! Global performance counters for observability and testing.
2//!
3//! Atomic counters that can be incremented from anywhere and read/reset in tests.
4//! All operations use relaxed ordering — these are best-effort metrics, not
5//! synchronization primitives.
6
7use std::sync::atomic::{AtomicU64, Ordering};
8use std::sync::LazyLock;
9
10static GLOBAL: LazyLock<Counters> = LazyLock::new(Counters::default);
11
12/// Access the global counters instance.
13pub fn global() -> &'static Counters {
14    &GLOBAL
15}
16
17#[derive(Debug, Default)]
18pub struct Counters {
19    /// Number of recovery chunk files loaded from disk.
20    pub recovery_chunks_loaded: AtomicU64,
21    /// Total bytes of recovery chunk data loaded into memory.
22    pub recovery_bytes_loaded: AtomicU64,
23    /// Total bytes read from disk via FileSystem trait methods.
24    pub disk_bytes_read: AtomicU64,
25}
26
27impl Counters {
28    pub fn reset(&self) {
29        self.recovery_chunks_loaded.store(0, Ordering::Relaxed);
30        self.recovery_bytes_loaded.store(0, Ordering::Relaxed);
31        self.disk_bytes_read.store(0, Ordering::Relaxed);
32    }
33
34    pub fn inc_recovery_chunks(&self, n: u64) {
35        self.recovery_chunks_loaded.fetch_add(n, Ordering::Relaxed);
36    }
37
38    pub fn inc_recovery_bytes(&self, n: u64) {
39        self.recovery_bytes_loaded.fetch_add(n, Ordering::Relaxed);
40    }
41
42    pub fn inc_disk_bytes_read(&self, n: u64) {
43        self.disk_bytes_read.fetch_add(n, Ordering::Relaxed);
44    }
45
46    pub fn get_recovery_chunks(&self) -> u64 {
47        self.recovery_chunks_loaded.load(Ordering::Relaxed)
48    }
49
50    pub fn get_recovery_bytes(&self) -> u64 {
51        self.recovery_bytes_loaded.load(Ordering::Relaxed)
52    }
53
54    pub fn get_disk_bytes_read(&self) -> u64 {
55        self.disk_bytes_read.load(Ordering::Relaxed)
56    }
57}