systemprompt_logging/services/
throttle.rs1use std::sync::atomic::{AtomicU64, Ordering};
10use std::time::{SystemTime, UNIX_EPOCH};
11
12#[derive(Debug)]
13pub struct LogThrottle {
14 interval_secs: u64,
15 last_emit_epoch_secs: AtomicU64,
16}
17
18impl LogThrottle {
19 #[must_use]
20 pub const fn new(interval_secs: u64) -> Self {
21 Self {
22 interval_secs,
23 last_emit_epoch_secs: AtomicU64::new(0),
24 }
25 }
26
27 #[must_use]
28 pub fn allow(&self) -> bool {
29 let now = SystemTime::now()
30 .duration_since(UNIX_EPOCH)
31 .map(|d| d.as_secs())
32 .unwrap_or_default();
33 self.allow_at(now)
34 }
35
36 #[must_use]
37 pub fn allow_at(&self, now_epoch_secs: u64) -> bool {
38 let last = self.last_emit_epoch_secs.load(Ordering::Acquire);
39 if last != 0 && now_epoch_secs.saturating_sub(last) < self.interval_secs {
40 return false;
41 }
42 self.last_emit_epoch_secs
43 .compare_exchange(last, now_epoch_secs, Ordering::AcqRel, Ordering::Relaxed)
44 .is_ok()
45 }
46}