pool: implement keepalive pinging
To prevent us from disconnecting, introduce keepalive pinging. In the event loop we check if any relays need a refresh ping.
This commit is contained in:
@@ -2,6 +2,8 @@ use crate::relay::message::RelayEvent;
|
||||
use crate::relay::Relay;
|
||||
use crate::{ClientMessage, Result};
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use ewebsock::WsMessage;
|
||||
|
||||
@@ -16,25 +18,42 @@ pub struct PoolEvent<'a> {
|
||||
pub event: RelayEvent,
|
||||
}
|
||||
|
||||
pub struct RelayPool {
|
||||
pub relays: Vec<Relay>,
|
||||
pub struct PoolRelay {
|
||||
pub relay: Relay,
|
||||
pub last_ping: Instant,
|
||||
}
|
||||
|
||||
impl Default for RelayPool {
|
||||
fn default() -> RelayPool {
|
||||
RelayPool { relays: Vec::new() }
|
||||
impl PoolRelay {
|
||||
pub fn new(relay: Relay) -> PoolRelay {
|
||||
PoolRelay {
|
||||
relay: relay,
|
||||
last_ping: Instant::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RelayPool {
|
||||
pub relays: Vec<PoolRelay>,
|
||||
pub ping_rate: Duration,
|
||||
}
|
||||
|
||||
impl RelayPool {
|
||||
// Constructs a new, empty RelayPool.
|
||||
pub fn new() -> RelayPool {
|
||||
RelayPool { relays: vec![] }
|
||||
RelayPool {
|
||||
relays: vec![],
|
||||
ping_rate: Duration::from_secs(25),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ping_rate(&mut self, duration: Duration) -> &mut Self {
|
||||
self.ping_rate = duration;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn has(&self, url: &str) -> bool {
|
||||
for relay in &self.relays {
|
||||
if &relay.url == url {
|
||||
if &relay.relay.url == url {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -43,12 +62,27 @@ impl RelayPool {
|
||||
|
||||
pub fn send(&mut self, cmd: &ClientMessage) {
|
||||
for relay in &mut self.relays {
|
||||
relay.send(cmd);
|
||||
relay.relay.send(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// Keep relay connectiongs alive by pinging relays that haven't been
|
||||
/// pinged in awhile. Adjust ping rate with [`ping_rate`].
|
||||
pub fn keepalive_ping(&mut self) {
|
||||
for relay in &mut self.relays {
|
||||
let now = std::time::Instant::now();
|
||||
let should_ping = now - relay.last_ping > self.ping_rate;
|
||||
if should_ping {
|
||||
debug!("pinging {}", relay.relay.url);
|
||||
relay.relay.ping();
|
||||
relay.last_ping = Instant::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_to(&mut self, cmd: &ClientMessage, relay_url: &str) {
|
||||
for relay in &mut self.relays {
|
||||
let relay = &mut relay.relay;
|
||||
if relay.url == relay_url {
|
||||
relay.send(cmd);
|
||||
return;
|
||||
@@ -63,8 +97,9 @@ impl RelayPool {
|
||||
wakeup: impl Fn() + Send + Sync + 'static,
|
||||
) -> Result<()> {
|
||||
let relay = Relay::new(url, wakeup)?;
|
||||
let pool_relay = PoolRelay::new(relay);
|
||||
|
||||
self.relays.push(relay);
|
||||
self.relays.push(pool_relay);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -72,6 +107,7 @@ impl RelayPool {
|
||||
/// Attempts to receive a pool event from a list of relays. The function searches each relay in the list in order, attempting to receive a message from each. If a message is received, return it. If no message is received from any relays, None is returned.
|
||||
pub fn try_recv(&mut self) -> Option<PoolEvent<'_>> {
|
||||
for relay in &mut self.relays {
|
||||
let relay = &mut relay.relay;
|
||||
if let Some(msg) = relay.receiver.try_recv() {
|
||||
match msg.try_into() {
|
||||
Ok(event) => {
|
||||
|
||||
Reference in New Issue
Block a user