lean_ctx/core/
cache_telemetry.rs1use std::sync::atomic::{AtomicU64, Ordering};
13
14static COMPACTION: AtomicU64 = AtomicU64::new(0);
15static IDLE: AtomicU64 = AtomicU64::new(0);
16static EVICTION: AtomicU64 = AtomicU64::new(0);
17static CONVERSATION: AtomicU64 = AtomicU64::new(0);
18static RAW_CAP_COUNT: AtomicU64 = AtomicU64::new(0);
19static RAW_CAP_PREVENTED: AtomicU64 = AtomicU64::new(0);
20
21pub fn record_compaction(n: u64) {
23 if n > 0 {
24 COMPACTION.fetch_add(n, Ordering::Relaxed);
25 }
26}
27
28pub fn record_idle(n: u64) {
30 if n > 0 {
31 IDLE.fetch_add(n, Ordering::Relaxed);
32 }
33}
34
35pub fn record_eviction(n: u64) {
37 if n > 0 {
38 EVICTION.fetch_add(n, Ordering::Relaxed);
39 }
40}
41
42pub fn record_conversation_mismatch() {
45 CONVERSATION.fetch_add(1, Ordering::Relaxed);
46}
47
48pub fn record_raw_cap(prevented_inflation_tokens: u64) {
52 RAW_CAP_COUNT.fetch_add(1, Ordering::Relaxed);
53 RAW_CAP_PREVENTED.fetch_add(prevented_inflation_tokens, Ordering::Relaxed);
54}
55
56#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
58pub struct Snapshot {
59 pub compaction: u64,
60 pub idle: u64,
61 pub eviction: u64,
62 pub conversation: u64,
63 pub raw_cap_count: u64,
64 pub raw_cap_prevented: u64,
65}
66
67impl Snapshot {
68 pub fn total(&self) -> u64 {
70 self.compaction
71 .saturating_add(self.idle)
72 .saturating_add(self.eviction)
73 .saturating_add(self.conversation)
74 }
75}
76
77pub fn snapshot() -> Snapshot {
79 Snapshot {
80 compaction: COMPACTION.load(Ordering::Relaxed),
81 idle: IDLE.load(Ordering::Relaxed),
82 eviction: EVICTION.load(Ordering::Relaxed),
83 conversation: CONVERSATION.load(Ordering::Relaxed),
84 raw_cap_count: RAW_CAP_COUNT.load(Ordering::Relaxed),
85 raw_cap_prevented: RAW_CAP_PREVENTED.load(Ordering::Relaxed),
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn total_sums_every_cause() {
95 let s = Snapshot {
96 compaction: 1,
97 idle: 2,
98 eviction: 4,
99 conversation: 8,
100 raw_cap_count: 0,
101 raw_cap_prevented: 0,
102 };
103 assert_eq!(s.total(), 15);
104 }
105
106 #[test]
107 fn zero_is_a_noop() {
108 let before = snapshot();
110 record_compaction(0);
111 record_idle(0);
112 record_eviction(0);
113 let after = snapshot();
116 assert!(after.compaction >= before.compaction);
117 assert!(after.idle >= before.idle);
118 assert!(after.eviction >= before.eviction);
119 }
120
121 #[test]
122 fn each_cause_increments_monotonically() {
123 let before = snapshot();
124 record_compaction(2);
125 record_idle(3);
126 record_eviction(5);
127 record_conversation_mismatch();
128 let after = snapshot();
129 assert!(after.compaction >= before.compaction + 2);
132 assert!(after.idle >= before.idle + 3);
133 assert!(after.eviction >= before.eviction + 5);
134 assert!(after.conversation > before.conversation);
135 assert!(after.total() >= before.total() + 11);
136 }
137}