1use coarsetime::{Clock, Updater};
16use ctor::ctor;
17use std::sync::LazyLock;
18
19static COARSE_CLOCK_UPDATER: LazyLock<Updater> = LazyLock::new(|| {
20 let interval = std::env::var("PINGAP_COARSE_CLOCK_INTERVAL")
21 .unwrap_or("10".to_string())
22 .parse::<u64>()
23 .unwrap_or(10)
24 .clamp(1, 500);
25 Updater::new(interval)
26 .start()
27 .expect("Failed to start coarse clock updater")
28});
29
30fn init_time_cache() {
32 LazyLock::force(&COARSE_CLOCK_UPDATER);
33}
34
35const SUPER_TIMESTAMP: u64 = 1651852800;
37
38#[inline]
40pub fn now_sec() -> u64 {
41 Clock::recent_since_epoch().as_secs()
42}
43
44#[inline]
47pub fn get_super_ts() -> u32 {
48 let super_ts_secs = SUPER_TIMESTAMP;
49 now_sec().saturating_sub(super_ts_secs) as u32
50}
51
52static HOST_NAME: LazyLock<String> = LazyLock::new(|| {
53 hostname::get()
54 .ok()
55 .as_deref()
56 .and_then(std::ffi::OsStr::to_str)
57 .unwrap_or("")
58 .to_string()
59});
60
61pub fn get_hostname() -> &'static str {
66 HOST_NAME.as_str()
67}
68
69#[inline]
71pub fn now_ms() -> u64 {
72 Clock::recent_since_epoch().as_millis()
73}
74
75#[inline]
78pub fn real_now_ms() -> u64 {
79 Clock::now_since_epoch().as_millis()
80}
81
82#[ctor]
83fn init() {
84 init_time_cache();
85}
86
87#[cfg(test)]
88mod tests {
89 use super::{
90 get_hostname, get_super_ts, init_time_cache, now_ms, real_now_ms,
91 };
92 use pretty_assertions::assert_eq;
93
94 #[test]
95 fn test_super_ts() {
96 init_time_cache();
97 assert_eq!(true, get_super_ts() > 104017048);
98 }
99
100 #[test]
101 fn test_now_ms() {
102 init_time_cache();
103 assert_eq!(true, now_ms() > 1755870295813);
104 }
105
106 #[test]
107 fn test_real_now_ms() {
108 init_time_cache();
109 assert_eq!(true, real_now_ms() > 1755870295813);
110 }
111
112 #[test]
113 fn test_get_hostname() {
114 assert_eq!(false, get_hostname().is_empty());
115 }
116}