atomr_remote/
deadline_detector.rs1use std::time::{Duration, Instant};
7
8use parking_lot::Mutex;
9
10use crate::failure_detector::FailureDetector;
11
12pub struct DeadlineFailureDetector {
13 pause: Duration,
14 last_heartbeat: Mutex<Option<Instant>>,
15}
16
17impl DeadlineFailureDetector {
18 pub fn new(acceptable_heartbeat_pause: Duration) -> Self {
19 Self { pause: acceptable_heartbeat_pause, last_heartbeat: Mutex::new(None) }
20 }
21}
22
23impl FailureDetector for DeadlineFailureDetector {
24 fn is_available(&self) -> bool {
25 match *self.last_heartbeat.lock() {
26 None => true,
27 Some(t) => t.elapsed() < self.pause,
28 }
29 }
30
31 fn is_monitoring(&self) -> bool {
32 self.last_heartbeat.lock().is_some()
33 }
34
35 fn heartbeat(&self) {
36 *self.last_heartbeat.lock() = Some(Instant::now());
37 }
38
39 fn reset(&self) {
40 *self.last_heartbeat.lock() = None;
41 }
42
43 fn since_last_heartbeat(&self) -> Option<Duration> {
44 self.last_heartbeat.lock().map(|t| t.elapsed())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn unavailable_after_pause() {
54 let d = DeadlineFailureDetector::new(Duration::from_millis(20));
55 d.heartbeat();
56 assert!(d.is_available());
57 std::thread::sleep(Duration::from_millis(30));
58 assert!(!d.is_available());
59 }
60}