improved timeout detection

This commit is contained in:
shimunn 2019-04-03 16:57:39 +02:00
parent d1daf3be00
commit a64fa75170

View File

@ -19,31 +19,39 @@ pub(crate) fn gen_events(
.map(|p| (*p, (prev.get(*p), state.get(*p)))) .map(|p| (*p, (prev.get(*p), state.get(*p))))
.collect::<HashMap<&ECCKey, (Option<&Peer>, Option<&Peer>)>>() .collect::<HashMap<&ECCKey, (Option<&Peer>, Option<&Peer>)>>()
}; };
let d_zero = Duration::from_secs(0);
let h_ms = Duration::from_millis(100);
for (_id, (prev, cur)) in side_by_side { for (_id, (prev, cur)) in side_by_side {
match (prev, cur) { match (prev, cur) {
(Some(prev), Some(cur)) => { (Some(prev), Some(cur)) => {
let timedout = |peer: &Peer| {
peer.last_handshake
.map(|shake| {
shake.elapsed().unwrap() > timeout
|| shake.elapsed().unwrap() + poll_interval < timeout
})
.unwrap_or(true)
};
if let (Some(prev_addr), Some(cur_addr)) = (prev.endpoint, cur.endpoint) { if let (Some(prev_addr), Some(cur_addr)) = (prev.endpoint, cur.endpoint) {
if prev_addr != cur_addr { if prev_addr != cur_addr {
listeners.roaming(&cur, prev_addr); listeners.roaming(&cur, prev_addr);
} }
} }
if !timedout(&prev) && timedout(&cur) { let timedout_now = || {
listeners.disconnected(&cur); if let Some(shake) = cur.last_handshake {
continue; if let Ok(el) = shake.elapsed() {
return el > timeout && el + poll_interval < timeout;
} }
}
true
};
if timedout(&prev) && !timedout(&cur) { let timedout_prev = || {
listeners.connected(&cur); if let Some(shake) = prev.last_handshake {
if let Ok(el) = shake.elapsed().map(|el| el - poll_interval) {
return el > timeout && el < timeout + poll_interval;
}
}
true
};
match (timedout_prev(), timedout_now()) {
(false, true) => listeners.disconnected(&cur),
(true, false) => listeners.connected(&cur),
other => (),
} }
} }
(None, Some(cur)) => listeners.added(&cur), (None, Some(cur)) => listeners.added(&cur),
@ -56,6 +64,7 @@ pub(crate) fn gen_events(
} }
} }
/*
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -88,31 +97,31 @@ mod test {
fn added<'a>(&self, peer: &'a Peer) { fn added<'a>(&self, peer: &'a Peer) {
self.calls self.calls
.borrow_mut() .borrow_mut()
.push(format!("add {}", peer.public_key)); .push(format!("add {}", peer.key));
} }
fn connected<'a>(&self, peer: &'a Peer) { fn connected<'a>(&self, peer: &'a Peer) {
self.calls self.calls
.borrow_mut() .borrow_mut()
.push(format!("con {}", peer.public_key)); .push(format!("con {}", peer.key));
} }
fn disconnected<'a>(&self, peer: &'a Peer) { fn disconnected<'a>(&self, peer: &'a Peer) {
self.calls self.calls
.borrow_mut() .borrow_mut()
.push(format!("dis {}", peer.public_key)); .push(format!("dis {}", peer.key));
} }
fn removed<'a>(&self, peer: &'a Peer) { fn removed<'a>(&self, peer: &'a Peer) {
self.calls self.calls
.borrow_mut() .borrow_mut()
.push(format!("rem {}", peer.public_key)); .push(format!("rem {}", peer.key));
} }
fn roaming<'a>(&self, peer: &'a Peer, _previous_addr: SocketAddr) { fn roaming<'a>(&self, peer: &'a Peer, _previous_addr: SocketAddr) {
self.calls self.calls
.borrow_mut() .borrow_mut()
.push(format!("rom {}", peer.public_key)); .push(format!("rom {}", peer.key));
} }
} }
@ -128,7 +137,7 @@ mod test {
let peer = peer(); let peer = peer();
listeners.connected(&peer); listeners.connected(&peer);
assert_eq!( assert_eq!(
vec![["con", &peer.public_key].join(" ")], vec![["con", &peer.key].join(" ")],
calls.borrow().clone() calls.borrow().clone()
); );
} }
@ -141,7 +150,7 @@ mod test {
let bkey = "HhRgEL2xsnEIqThSTUKLGaTXusorM1MFdjSSYvzBynY="; let bkey = "HhRgEL2xsnEIqThSTUKLGaTXusorM1MFdjSSYvzBynY=";
let key = b2h(bkey); let key = b2h(bkey);
Peer::from_kv(&vec![ Peer::from_kv(&vec![
("public_key".to_string(), key.clone()), ("key".to_string(), key.clone()),
/*( /*(
"last_handshake_time_nsec".to_string(), "last_handshake_time_nsec".to_string(),
(1000 * 1000 * 1).to_string(), (1000 * 1000 * 1).to_string(),
@ -157,7 +166,7 @@ mod test {
let mut peer_cur = peer.clone(); let mut peer_cur = peer.clone();
let mut prev: HashMap<String, Peer> = HashMap::new(); let mut prev: HashMap<String, Peer> = HashMap::new();
let mut cur: HashMap<String, Peer> = HashMap::new(); let mut cur: HashMap<String, Peer> = HashMap::new();
cur.insert(peer_cur.public_key.clone(), peer_cur.clone()); cur.insert(peer_cur.key.clone(), peer_cur.clone());
let (listener, calls) = listeners(); let (listener, calls) = listeners();
let interval = time::Duration::from_secs(3); let interval = time::Duration::from_secs(3);
gen_events( gen_events(
@ -168,7 +177,7 @@ mod test {
interval, interval,
); );
assert_eq!( assert_eq!(
vec![["add", &peer_cur.public_key].join(" ")], vec![["add", &peer_cur.key].join(" ")],
calls.borrow().clone() calls.borrow().clone()
); );
@ -192,7 +201,7 @@ mod test {
interval, interval,
); );
assert_eq!( assert_eq!(
vec![["rem", &peer.public_key].join(" ")], vec![["rem", &peer.key].join(" ")],
calls.borrow().clone() calls.borrow().clone()
); );
@ -204,7 +213,7 @@ mod test {
peer_prev.last_handshake = Some(time::Duration::from_secs(1000)); peer_prev.last_handshake = Some(time::Duration::from_secs(1000));
prev.insert(peer_prev.public_key.clone(), peer_prev.clone()); prev.insert(peer_prev.key.clone(), peer_prev.clone());
gen_events( gen_events(
&prev, &prev,
@ -217,7 +226,7 @@ mod test {
assert!(calls assert!(calls
.borrow() .borrow()
.clone() .clone()
.contains(&["rom", &peer.public_key].join(" "))); .contains(&["rom", &peer.key].join(" ")));
calls.borrow_mut().clear(); calls.borrow_mut().clear();
@ -225,8 +234,8 @@ mod test {
peer_cur.last_handshake = Some(time::Duration::from_secs(5)); peer_cur.last_handshake = Some(time::Duration::from_secs(5));
cur.insert(peer_cur.public_key.clone(), peer_cur.clone()); cur.insert(peer_cur.key.clone(), peer_cur.clone());
prev.insert(peer_prev.public_key.clone(), peer_prev.clone()); prev.insert(peer_prev.key.clone(), peer_prev.clone());
gen_events( gen_events(
&cur, &cur,
@ -237,7 +246,7 @@ mod test {
); );
assert_eq!( assert_eq!(
vec![["con", &peer.public_key].join(" ")], vec![["con", &peer.key].join(" ")],
calls.borrow().clone() calls.borrow().clone()
); );
@ -253,9 +262,9 @@ mod test {
); );
assert_eq!( assert_eq!(
vec![["dis", &peer.public_key].join(" ")], vec![["dis", &peer.key].join(" ")],
calls.borrow().clone() calls.borrow().clone()
); );
} }
} }*/