parent
12f82e72f0
commit
ab30a684bd
@ -1,6 +1,6 @@
|
||||
/target
|
||||
.idea
|
||||
*.env
|
||||
test
|
||||
config
|
||||
nodes
|
||||
testdata
|
@ -0,0 +1,58 @@
|
||||
use crate::modules::Module;
|
||||
use vented::server::VentedServer;
|
||||
use crate::utils::result::SnekcloudResult;
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use vented::result::{VentedResult};
|
||||
use crate::modules::heartbeat::payloads::HeartbeatPayload;
|
||||
use std::time::{Instant, Duration};
|
||||
use vented::event::Event;
|
||||
|
||||
mod payloads;
|
||||
const HEARTBEAT_BEAT_EVENT: &str = "heartbeat:beat";
|
||||
const HEARTBEAT_RATE_SECONDS: u64 = 10;
|
||||
|
||||
pub struct HeartbeatModule {
|
||||
last_tick: Instant,
|
||||
}
|
||||
|
||||
impl HeartbeatModule {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
last_tick: Instant::now()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for HeartbeatModule {
|
||||
fn name(&self) -> String {
|
||||
"HeartbeatModule".to_string()
|
||||
}
|
||||
|
||||
fn init(&mut self, server: &mut VentedServer, _: &mut ScheduledThreadPool) -> SnekcloudResult<()> {
|
||||
server.on(HEARTBEAT_BEAT_EVENT, |event| {
|
||||
let payload = event.get_payload::<HeartbeatPayload>().unwrap();
|
||||
log::debug!("Latency to node {} is {} ms", payload.node_id, payload.get_beat_time().elapsed().unwrap().as_millis());
|
||||
|
||||
None
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn boxed(self) -> Box<dyn Module> {
|
||||
Box::new(self)
|
||||
}
|
||||
|
||||
fn tick(&mut self, server: &mut VentedServer, _: &mut ScheduledThreadPool) -> VentedResult<()> {
|
||||
if self.last_tick.elapsed() > Duration::from_secs(HEARTBEAT_RATE_SECONDS) {
|
||||
for node in server.nodes() {
|
||||
if let Err(e) = server.emit(node.id.clone(), Event::with_payload(HEARTBEAT_BEAT_EVENT, &HeartbeatPayload::now(server.node_id()))) {
|
||||
log::warn!("Node {} is not reachable: {}", node.id, e)
|
||||
}
|
||||
}
|
||||
self.last_tick = Instant::now();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::time::{ UNIX_EPOCH, Duration, SystemTime};
|
||||
use std::ops::Add;
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HeartbeatPayload {
|
||||
pub node_id: String,
|
||||
beat_at: u64,
|
||||
}
|
||||
|
||||
impl HeartbeatPayload {
|
||||
pub fn now(node_id: String) -> Self {
|
||||
let start = SystemTime::now();
|
||||
Self {
|
||||
node_id,
|
||||
beat_at: start.duration_since(UNIX_EPOCH).unwrap().as_millis() as u64
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_beat_time(&self) -> SystemTime {
|
||||
UNIX_EPOCH.add(Duration::from_millis(self.beat_at))
|
||||
}
|
||||
}
|
@ -1,6 +1,13 @@
|
||||
use vented::server::VentedServer;
|
||||
use crate::utils::result::SnekcloudResult;
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use vented::result::VentedResult;
|
||||
|
||||
pub mod heartbeat;
|
||||
|
||||
pub trait Module {
|
||||
fn init(&mut self, server: &VentedServer) -> SnekcloudResult<()>;
|
||||
fn name(&self) -> String;
|
||||
fn init(&mut self, server: &mut VentedServer, pool: &mut ScheduledThreadPool) -> SnekcloudResult<()>;
|
||||
fn boxed(self) -> Box<dyn Module>;
|
||||
fn tick(&mut self, server: &mut VentedServer, pool: &mut ScheduledThreadPool) -> VentedResult<()>;
|
||||
}
|
Loading…
Reference in New Issue