forge_core/cluster/
traits.rs1use super::node::NodeId;
2use super::roles::LeaderRole;
3
4#[derive(Debug, Clone)]
6pub struct ClusterInfo {
7 pub name: String,
9 pub total_nodes: usize,
11 pub active_nodes: usize,
13 pub draining_nodes: usize,
15 pub dead_nodes: usize,
17 pub scheduler_leader: Option<NodeId>,
19}
20
21impl ClusterInfo {
22 pub fn empty(name: impl Into<String>) -> Self {
24 Self {
25 name: name.into(),
26 total_nodes: 0,
27 active_nodes: 0,
28 draining_nodes: 0,
29 dead_nodes: 0,
30 scheduler_leader: None,
31 }
32 }
33}
34
35#[derive(Debug, Clone)]
37pub struct LeaderInfo {
38 pub role: LeaderRole,
40 pub node_id: NodeId,
42 pub acquired_at: chrono::DateTime<chrono::Utc>,
44 pub lease_until: chrono::DateTime<chrono::Utc>,
46}
47
48impl LeaderInfo {
49 pub fn is_valid(&self) -> bool {
51 self.lease_until > chrono::Utc::now()
52 }
53}
54
55#[cfg(test)]
56#[allow(clippy::unwrap_used, clippy::indexing_slicing)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn test_cluster_info_empty() {
62 let info = ClusterInfo::empty("test-cluster");
63 assert_eq!(info.name, "test-cluster");
64 assert_eq!(info.total_nodes, 0);
65 assert_eq!(info.active_nodes, 0);
66 assert!(info.scheduler_leader.is_none());
67 }
68
69 #[test]
70 fn test_leader_info_validity() {
71 let node_id = NodeId::new();
72 let info = LeaderInfo {
73 role: LeaderRole::Scheduler,
74 node_id,
75 acquired_at: chrono::Utc::now(),
76 lease_until: chrono::Utc::now() + chrono::Duration::minutes(1),
77 };
78 assert!(info.is_valid());
79
80 let expired_info = LeaderInfo {
81 role: LeaderRole::Scheduler,
82 node_id,
83 acquired_at: chrono::Utc::now() - chrono::Duration::minutes(5),
84 lease_until: chrono::Utc::now() - chrono::Duration::minutes(1),
85 };
86 assert!(!expired_info.is_valid());
87 }
88}