synchronous_timer/
lib.rs

1//! This module implements a relatively simple synchronous Timer/Scheduler backed by the standard library BinaryHeap type. It is suitable for a reasonably large number of tasks, but you should really use some kind of timer-wheel implementation if you want to have millions and millions of tasks.
2//!
3//! # Panics
4//! Panics in a scheduled task will be caught and logged; repeating task will *not* be rerun after they panics.
5//!
6mod executor;
7mod task;
8mod timer;
9
10pub use task::TaskGuard;
11pub use timer::Timer;
12
13#[cfg(test)]
14mod tests {
15    use std::sync::atomic::{AtomicU32, Ordering};
16    use std::sync::Arc;
17    use std::time::{Duration, SystemTime};
18
19    use super::Timer;
20
21    #[test]
22    fn test_once() {
23        let mut t = Timer::new();
24        let h = Arc::new(AtomicU32::new(0));
25        let h2 = Arc::clone(&h);
26        t.schedule_in(Duration::from_millis(10), move || {
27            h2.fetch_add(1, Ordering::SeqCst);
28        })
29        .detach();
30        std::thread::sleep(Duration::from_millis(100));
31        assert_eq!(h.load(Ordering::SeqCst), 1);
32    }
33
34    #[test]
35    fn test_repeating() {
36        let mut t = Timer::new();
37        let h = Arc::new(AtomicU32::new(0));
38        let h2 = Arc::clone(&h);
39        t.schedule_repeating(Duration::from_millis(10), move || {
40            h2.fetch_add(1, Ordering::SeqCst);
41        })
42        .detach();
43        std::thread::sleep(Duration::from_millis(100));
44        let ran = h.load(Ordering::SeqCst);
45        assert!(ran > 7);
46        assert!(ran < 11);
47    }
48
49    #[test]
50    fn test_drop() {
51        let mut t = Timer::new();
52        let h = Arc::new(AtomicU32::new(0));
53        let h2 = Arc::clone(&h);
54        let guard = t.schedule_in(Duration::from_millis(10), move || {
55            h2.fetch_add(1, Ordering::SeqCst);
56        });
57        drop(guard);
58        std::thread::sleep(Duration::from_millis(100));
59        assert_eq!(h.load(Ordering::SeqCst), 0);
60    }
61
62    #[test]
63    fn test_schedule_immediately() {
64        let mut t = Timer::new();
65        let h = Arc::new(AtomicU32::new(0));
66        let h2 = Arc::clone(&h);
67        t.schedule_immediately(move || {
68            h2.fetch_add(1, Ordering::SeqCst);
69        });
70        std::thread::sleep(Duration::from_millis(100));
71        assert_eq!(h.load(Ordering::SeqCst), 1);
72    }
73
74    #[test]
75    fn test_schedule_at() {
76        let mut t = Timer::new();
77        let h = Arc::new(AtomicU32::new(0));
78        let h2 = Arc::clone(&h);
79        t.schedule_at(SystemTime::now() + Duration::from_millis(50), move || {
80            h2.fetch_add(1, Ordering::SeqCst);
81        })
82        .detach();
83        std::thread::sleep(Duration::from_millis(100));
84        assert_eq!(h.load(Ordering::SeqCst), 1);
85    }
86}