Skip to content

Commit b33fca3

Browse files
committed
Merge branch 'master' into build/docker-image
2 parents 69da5ce + 2c74cfa commit b33fca3

File tree

1 file changed

+72
-28
lines changed

1 file changed

+72
-28
lines changed

src/masternode_cache.rs

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,77 +59,121 @@ impl MasternodeCache {
5959

6060
async fn update_cache(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
6161
println!("Updating masternode cache...");
62-
62+
63+
// Wrap the entire operation in a timeout (30 seconds)
64+
let result = tokio::time::timeout(
65+
tokio::time::Duration::from_secs(30),
66+
self.update_cache_internal()
67+
).await;
68+
69+
match result {
70+
Ok(Ok(())) => Ok(()),
71+
Ok(Err(e)) => Err(e),
72+
Err(_) => {
73+
eprintln!("⚠️ CACHE UPDATE TIMED OUT after 30 seconds - this indicates network issues or too many slow nodes");
74+
Err("Cache update timed out after 30 seconds".into())
75+
}
76+
}
77+
}
78+
79+
async fn update_cache_internal(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
6380
// Fetch new data
6481
let mut masternodes = masternode_loader::load_masternode_list(&self.config).await?;
65-
82+
6683
println!("Checking version for {} Evo masternodes...", masternodes.len());
6784

6885
// Check version for each masternode
6986
let check_tasks: Vec<_> = masternodes.iter().enumerate().map(|(idx, node)| {
7087
let address = node.address.clone();
7188
let status = node.status.clone();
72-
89+
let config = self.config.clone();
90+
7391
async move {
92+
let start = std::time::Instant::now();
93+
7494
// Skip POSE_BANNED nodes
7595
if status == "POSE_BANNED" {
7696
println!("⏭️ Node {} at {} - skipping (POSE_BANNED)", idx, address);
77-
return (idx, "fail".to_string(), None, None);
97+
return (idx, "fail".to_string(), None, None, start.elapsed());
7898
}
79-
99+
80100
// Parse address to get IP and port
81101
let parts: Vec<&str> = address.split(':').collect();
82102
if parts.len() != 2 {
83103
println!("❌ Node {} at {} - invalid address format", idx, address);
84-
return (idx, "fail".to_string(), None, None);
104+
return (idx, "fail".to_string(), None, None, start.elapsed());
85105
}
86-
106+
87107
let ip = parts[0];
88-
let port = self.config.get_dapi_port();
89-
108+
let port = config.get_dapi_port();
109+
90110
println!("🔍 Node {} at {} - checking version...", idx, address);
91-
92-
// Check version with additional timeout wrapper (3 seconds total)
93-
match tokio::time::timeout(
94-
tokio::time::Duration::from_secs(3),
111+
112+
// Check version with additional timeout wrapper (2 seconds total)
113+
let result = match tokio::time::timeout(
114+
tokio::time::Duration::from_secs(2),
95115
grpc_client::check_node_version(ip, port)
96116
).await {
97117
Ok(Ok(result)) => {
118+
let elapsed = start.elapsed();
98119
if result.success {
99-
println!("✓ Node {} at {} - version 2.0+ (DAPI: {:?}, Drive: {:?})",
100-
idx, address, result.dapi_version, result.drive_version);
101-
(idx, "success".to_string(), result.dapi_version, result.drive_version)
120+
println!("✓ Node {} at {} - version 2.0+ (DAPI: {:?}, Drive: {:?}) [took {:?}]",
121+
idx, address, result.dapi_version, result.drive_version, elapsed);
122+
(idx, "success".to_string(), result.dapi_version, result.drive_version, elapsed)
102123
} else {
103-
println!("✗ Node {} at {} - version < 2.0 (DAPI: {:?}, Drive: {:?})",
104-
idx, address, result.dapi_version, result.drive_version);
105-
(idx, "fail".to_string(), result.dapi_version, result.drive_version)
124+
println!("✗ Node {} at {} - version < 2.0 (DAPI: {:?}, Drive: {:?}) [took {:?}]",
125+
idx, address, result.dapi_version, result.drive_version, elapsed);
126+
(idx, "fail".to_string(), result.dapi_version, result.drive_version, elapsed)
106127
}
107128
},
108129
Ok(Err(e)) => {
109-
println!("✗ Node {} at {} - error: {}", idx, address, e);
110-
(idx, "fail".to_string(), None, None)
130+
let elapsed = start.elapsed();
131+
println!("✗ Node {} at {} - error: {} [took {:?}]", idx, address, e, elapsed);
132+
(idx, "fail".to_string(), None, None, elapsed)
111133
},
112134
Err(_) => {
113-
println!("✗ Node {} at {} - timeout after 3 seconds", idx, address);
114-
(idx, "fail".to_string(), None, None)
135+
let elapsed = start.elapsed();
136+
println!("⏱️ Node {} at {} - TIMEOUT after {:?} ⚠️ THIS NODE IS SLOW!", idx, address, elapsed);
137+
(idx, "fail".to_string(), None, None, elapsed)
115138
},
116-
}
139+
};
140+
result
117141
}
118142
}).collect();
119143

120144
// Execute all version checks concurrently
145+
let overall_start = std::time::Instant::now();
121146
let results = futures::future::join_all(check_tasks).await;
122-
147+
let total_elapsed = overall_start.elapsed();
148+
149+
// Track slow nodes
150+
let mut slow_nodes: Vec<(usize, String, std::time::Duration)> = vec![];
151+
123152
// Update the version_check field and version info for each masternode
124-
for (idx, version_check, dapi_version, drive_version) in results {
153+
for (idx, version_check, dapi_version, drive_version, elapsed) in results {
125154
masternodes[idx].version_check = version_check;
126155
masternodes[idx].dapi_version = dapi_version;
127156
masternodes[idx].drive_version = drive_version;
157+
158+
// Track nodes that took more than 2 seconds
159+
if elapsed.as_secs() >= 2 {
160+
slow_nodes.push((idx, masternodes[idx].address.clone(), elapsed));
161+
}
128162
}
129-
163+
130164
let success_count = masternodes.iter().filter(|n| n.version_check == "success").count();
131165
let fail_count = masternodes.iter().filter(|n| n.version_check == "fail").count();
132-
println!("Version check complete: {} success, {} fail", success_count, fail_count);
166+
println!("Version check complete: {} success, {} fail (total time: {:?})", success_count, fail_count, total_elapsed);
167+
168+
// Report slow nodes
169+
if !slow_nodes.is_empty() {
170+
println!("\n🐌 SLOW NODES DETECTED ({} nodes took >2s):", slow_nodes.len());
171+
slow_nodes.sort_by(|a, b| b.2.cmp(&a.2)); // Sort by duration, slowest first
172+
for (idx, address, duration) in slow_nodes.iter().take(10) {
173+
println!(" Node {} at {} took {:?}", idx, address, duration);
174+
}
175+
println!();
176+
}
133177

134178
// Update the cache
135179
{

0 commit comments

Comments
 (0)