#![allow(dead_code)]
mod node_manager;
mod parser;
mod redis_ops;
use anyhow::Result;
use std::collections::HashMap;
use std::time::{Duration, SystemTime};
#[derive(Debug, Clone)]
pub struct NodeInfo {
pub node_id: String,
pub node_type: String,
pub host: String,
pub port: u16,
pub last_seen: SystemTime,
pub metadata: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct DiscoveryConfig {
pub redis_url: String,
pub discovery_topic: String,
pub heartbeat_interval: Duration,
pub node_timeout: Duration,
pub scan_subnet: Option<String>,
}
impl Default for DiscoveryConfig {
fn default() -> Self {
Self {
redis_url: "redis://localhost:6379".to_string(),
discovery_topic: "mecha10/discovery".to_string(),
heartbeat_interval: Duration::from_secs(5),
node_timeout: Duration::from_secs(30),
scan_subnet: None,
}
}
}
pub struct DiscoveryService {
discovered_nodes: HashMap<String, NodeInfo>,
}
impl DiscoveryService {
pub fn new() -> Self {
Self {
discovered_nodes: HashMap::new(),
}
}
pub async fn discover(&mut self, config: &DiscoveryConfig) -> Result<Vec<NodeInfo>> {
redis_ops::discover(config, &mut self.discovered_nodes).await
}
pub async fn monitor<F>(&mut self, config: &DiscoveryConfig, callback: F) -> Result<()>
where
F: FnMut(&NodeInfo),
{
redis_ops::monitor(config, &mut self.discovered_nodes, callback).await
}
pub fn get_nodes(&self) -> Vec<&NodeInfo> {
node_manager::get_nodes(&self.discovered_nodes)
}
pub fn get_node(&self, node_id: &str) -> Option<&NodeInfo> {
node_manager::get_node(&self.discovered_nodes, node_id)
}
pub fn cleanup_stale_nodes(&mut self, timeout: Duration) -> usize {
node_manager::cleanup_stale_nodes(&mut self.discovered_nodes, timeout)
}
pub async fn announce(&self, config: &DiscoveryConfig, node_info: &NodeInfo) -> Result<()> {
redis_ops::announce(config, node_info).await
}
pub async fn heartbeat(&self, config: &DiscoveryConfig, node_id: &str) -> Result<()> {
redis_ops::heartbeat(config, node_id).await
}
pub fn node_count(&self) -> usize {
node_manager::node_count(&self.discovered_nodes)
}
pub fn get_nodes_by_type(&self, node_type: &str) -> Vec<&NodeInfo> {
node_manager::get_nodes_by_type(&self.discovered_nodes, node_type)
}
pub fn clear(&mut self) {
node_manager::clear(&mut self.discovered_nodes);
}
}
impl Default for DiscoveryService {
fn default() -> Self {
Self::new()
}
}