1use std::time::Instant;
2use tracing::{debug, warn};
3
4#[derive(Debug, Clone)]
6pub struct GlobalTimer {
7 pub base_timestamp: i64,
9 pub base_instant: Instant,
11 pub last_sync_at: Instant,
13}
14
15impl GlobalTimer {
16 pub fn new(initial_timestamp: i64) -> Self {
18 let base_instant = Instant::now();
19 debug!("初始化全局计时器,时间戳: {}", initial_timestamp);
20
21 Self {
22 base_timestamp: initial_timestamp,
23 base_instant,
24 last_sync_at: base_instant,
25 }
26 }
27
28 pub fn get_current_timestamp(&self) -> i64 {
30 let elapsed_secs = self.base_instant.elapsed().as_secs() as i64;
31 self.base_timestamp + elapsed_secs
32 }
33
34 pub fn detect_clock_jump(&self, new_ntp_timestamp: i64, threshold: i64) -> bool {
36 let current_estimate = self.get_current_timestamp();
37 let drift = (new_ntp_timestamp - current_estimate).abs();
38
39 if drift > threshold {
40 warn!(
41 drift_secs = drift,
42 threshold_secs = threshold,
43 "检测到系统时钟跳跃"
44 );
45 true
46 } else {
47 debug!(drift_secs = drift, "系统时钟漂移在正常范围内");
48 false
49 }
50 }
51
52 pub fn update_timestamp(&mut self, new_timestamp: i64, is_jump: bool) {
54 self.base_timestamp = new_timestamp;
55 self.base_instant = Instant::now();
56 self.last_sync_at = self.base_instant;
57
58 if is_jump {
59 warn!("检测到系统时钟跳跃,重新初始化计时器");
60 } else {
61 debug!("基准时间戳已更新(漂移纠正)");
62 }
63 }
64
65 pub fn should_sync(&self, sync_interval: u64) -> bool {
67 self.last_sync_at.elapsed().as_secs() >= sync_interval
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use std::thread;
75
76 #[test]
77 fn test_timer_creation() {
78 let timer = GlobalTimer::new(1000);
79 assert_eq!(timer.base_timestamp, 1000);
80 }
81
82 #[test]
83 fn test_get_current_timestamp() {
84 let timer = GlobalTimer::new(1000);
85 thread::sleep(std::time::Duration::from_millis(100));
86 let ts = timer.get_current_timestamp();
87 assert!(ts >= 1000);
88 }
89
90 #[test]
91 fn test_detect_clock_jump() {
92 let timer = GlobalTimer::new(1000);
93 assert!(!timer.detect_clock_jump(1001, 5));
94 assert!(timer.detect_clock_jump(1010, 5));
95 }
96
97 #[test]
98 fn test_update_timestamp() {
99 let mut timer = GlobalTimer::new(1000);
100 timer.update_timestamp(2000, true);
101 assert_eq!(timer.base_timestamp, 2000);
102 }
103
104 #[test]
105 fn test_should_sync() {
106 let timer = GlobalTimer::new(1000);
107 assert!(!timer.should_sync(10));
108 thread::sleep(std::time::Duration::from_secs(1));
109 assert!(timer.should_sync(0));
110 }
111}