use crate::error::CoreResult;
use std::collections::HashMap;
use super::types::{NodeInfo, NodeStatus};
#[derive(Debug)]
pub struct NodeRegistry {
nodes: HashMap<String, NodeInfo>,
node_status: HashMap<String, NodeStatus>,
}
impl Default for NodeRegistry {
fn default() -> Self {
Self::new()
}
}
impl NodeRegistry {
pub fn new() -> Self {
Self {
nodes: HashMap::new(),
node_status: HashMap::new(),
}
}
pub fn register_node(&mut self, nodeinfo: NodeInfo) -> CoreResult<bool> {
let is_new = !self.nodes.contains_key(&nodeinfo.id);
self.nodes.insert(nodeinfo.id.clone(), nodeinfo.clone());
self.node_status
.insert(nodeinfo.id.clone(), nodeinfo.status);
Ok(is_new)
}
pub fn get_all_nodes(&self) -> Vec<NodeInfo> {
self.nodes.values().cloned().collect()
}
pub fn get_healthy_nodes(&self) -> Vec<NodeInfo> {
self.nodes
.values()
.filter(|node| self.node_status.get(&node.id) == Some(&NodeStatus::Healthy))
.cloned()
.collect()
}
pub fn get_nodes_by_status(&self, status: NodeStatus) -> Vec<NodeInfo> {
self.nodes
.values()
.filter(|node| self.node_status.get(&node.id) == Some(&status))
.cloned()
.collect()
}
pub fn get_node(&self, nodeid: &str) -> Option<&NodeInfo> {
self.nodes.get(nodeid)
}
pub fn get_node_status(&self, nodeid: &str) -> Option<NodeStatus> {
self.node_status.get(nodeid).copied()
}
pub fn update_node_status(&mut self, nodeid: &str, status: NodeStatus) -> CoreResult<()> {
if let Some(node) = self.nodes.get_mut(nodeid) {
node.status = status;
self.node_status.insert(nodeid.to_string(), status);
}
Ok(())
}
pub fn remove_node(&mut self, nodeid: &str) -> Option<NodeInfo> {
self.node_status.remove(nodeid);
self.nodes.remove(nodeid)
}
pub fn node_count(&self) -> usize {
self.nodes.len()
}
pub fn healthy_node_count(&self) -> usize {
self.get_healthy_nodes().len()
}
pub fn contains_node(&self, nodeid: &str) -> bool {
self.nodes.contains_key(nodeid)
}
pub fn clear(&mut self) {
self.nodes.clear();
self.node_status.clear();
}
pub fn get_stale_nodes(&self, max_age: std::time::Duration) -> Vec<NodeInfo> {
let now = std::time::Instant::now();
self.nodes
.values()
.filter(|node| now.duration_since(node.last_seen) > max_age)
.cloned()
.collect()
}
pub fn update_node_last_seen(&mut self, nodeid: &str) {
if let Some(node) = self.nodes.get_mut(nodeid) {
node.last_seen = std::time::Instant::now();
}
}
}