1use std::sync::{
4 Arc,
5 atomic::{AtomicI64, Ordering},
6};
7
8use crate::{Timestamp, timestamp};
9
10#[derive(Debug, Clone, Default)]
18pub struct ServerClock {
19 offset_ms: Arc<AtomicI64>,
20}
21
22impl ServerClock {
23 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn offset(&self) -> i64 {
30 self.offset_ms.load(Ordering::Relaxed)
31 }
32
33 pub fn set_offset(&self, offset_ms: i64) {
35 self.offset_ms.store(offset_ms, Ordering::Relaxed);
36 }
37
38 pub fn now(&self) -> Timestamp {
40 timestamp().saturating_add_signed(self.offset())
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn clones_share_the_offset() {
50 let clock = ServerClock::new();
51 let clone = clock.clone();
52
53 clone.set_offset(60_000);
54
55 assert_eq!(clock.offset(), 60_000);
56 let skew = clock.now() as i64 - (timestamp() as i64 + 60_000);
57 assert!(skew.abs() < 1000);
58 }
59}