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)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_cluster_info_empty() {
61 let info = ClusterInfo::empty("test-cluster");
62 assert_eq!(info.name, "test-cluster");
63 assert_eq!(info.total_nodes, 0);
64 assert_eq!(info.active_nodes, 0);
65 assert!(info.scheduler_leader.is_none());
66 }
67
68 #[test]
69 fn test_leader_info_validity() {
70 let node_id = NodeId::new();
71 let info = LeaderInfo {
72 role: LeaderRole::Scheduler,
73 node_id,
74 acquired_at: chrono::Utc::now(),
75 lease_until: chrono::Utc::now() + chrono::Duration::minutes(1),
76 };
77 assert!(info.is_valid());
78
79 let expired_info = LeaderInfo {
80 role: LeaderRole::Scheduler,
81 node_id,
82 acquired_at: chrono::Utc::now() - chrono::Duration::minutes(5),
83 lease_until: chrono::Utc::now() - chrono::Duration::minutes(1),
84 };
85 assert!(!expired_info.is_valid());
86 }
87}