1use std::sync::Arc;
18use std::time::Duration;
19
20use common_time::util::current_time_millis;
21
22pub trait TimeProvider: std::fmt::Debug + Send + Sync {
26 fn current_time_millis(&self) -> i64;
28
29 fn elapsed_since(&self, current_millis: i64) -> i64;
31
32 fn wait_duration(&self, duration: Duration) -> Duration {
34 duration
35 }
36}
37
38pub type TimeProviderRef = Arc<dyn TimeProvider>;
39
40#[derive(Debug)]
42pub struct StdTimeProvider;
43
44impl TimeProvider for StdTimeProvider {
45 fn current_time_millis(&self) -> i64 {
46 current_time_millis()
47 }
48
49 fn elapsed_since(&self, current_millis: i64) -> i64 {
50 current_time_millis() - current_millis
51 }
52}
53
54#[cfg(test)]
56pub(crate) mod mock {
57 use std::sync::atomic::{AtomicI64, Ordering};
58 use std::time::Duration;
59
60 use crate::time_provider::TimeProvider;
61
62 #[derive(Debug)]
63 pub(crate) struct MockTimeProvider {
64 now: AtomicI64,
65 elapsed: AtomicI64,
66 }
67
68 impl TimeProvider for MockTimeProvider {
69 fn current_time_millis(&self) -> i64 {
70 self.now.load(Ordering::Relaxed)
71 }
72
73 fn elapsed_since(&self, _current_millis: i64) -> i64 {
74 self.elapsed.load(Ordering::Relaxed)
75 }
76
77 fn wait_duration(&self, _duration: Duration) -> Duration {
78 Duration::from_millis(20)
79 }
80 }
81
82 impl MockTimeProvider {
83 pub(crate) fn new(now: i64) -> Self {
84 Self {
85 now: AtomicI64::new(now),
86 elapsed: AtomicI64::new(0),
87 }
88 }
89
90 pub(crate) fn set_now(&self, now: i64) {
91 self.now.store(now, Ordering::Relaxed);
92 }
93
94 pub(crate) fn set_elapsed(&self, elapsed: i64) {
95 self.elapsed.store(elapsed, Ordering::Relaxed);
96 }
97 }
98}