-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode_status.rs
More file actions
101 lines (88 loc) · 2.3 KB
/
Copy pathnode_status.rs
File metadata and controls
101 lines (88 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Node Status Management
//!
//! Tracks health and load of network nodes.
use chrono::{DateTime, Utc};
use std::collections::HashMap;
/// Node status information
#[derive(Debug, Clone)]
pub struct NodeStatus {
/// Node DID
pub did: String,
/// Is node online
pub online: bool,
/// Current load (0.0 - 1.0)
pub load: f32,
/// Average latency in ms
pub avg_latency_ms: u64,
/// Last heartbeat
pub last_heartbeat: DateTime<Utc>,
/// Total calls served
pub total_calls: u64,
/// Failed calls
pub failed_calls: u64,
}
impl NodeStatus {
/// Create a new node status
pub fn new(did: &str) -> Self {
Self {
did: did.to_string(),
online: true,
load: 0.0,
avg_latency_ms: 0,
last_heartbeat: Utc::now(),
total_calls: 0,
failed_calls: 0,
}
}
/// Get success rate
pub fn success_rate(&self) -> f32 {
if self.total_calls == 0 {
return 1.0;
}
(self.total_calls - self.failed_calls) as f32 / self.total_calls as f32
}
}
/// Node status manager
#[derive(Debug, Clone, Default)]
pub struct NodeStatusManager {
/// Node statuses by DID
statuses: HashMap<String, NodeStatus>,
}
impl NodeStatusManager {
/// Create a new manager
pub fn new() -> Self {
Self::default()
}
/// Update node status
pub fn update(&mut self, status: NodeStatus) {
self.statuses.insert(status.did.clone(), status);
}
/// Get node status
pub fn get(&self, did: &str) -> Option<&NodeStatus> {
self.statuses.get(did)
}
/// Check if node is healthy
pub fn is_healthy(&self, did: &str) -> bool {
self.statuses
.get(did)
.map(|s| s.online && s.success_rate() > 0.9)
.unwrap_or(false)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_status() {
let status = NodeStatus::new("did:nexa:test");
assert!(status.online);
assert_eq!(status.success_rate(), 1.0);
}
#[test]
fn test_status_manager() {
let mut manager = NodeStatusManager::new();
let status = NodeStatus::new("did:nexa:test");
manager.update(status);
assert!(manager.is_healthy("did:nexa:test"));
}
}