From 672c8bebc9f8a98fb41dcbc8a4ee080791ea3d54 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Tue, 14 Oct 2025 23:22:30 +0200 Subject: [PATCH] Fix recursive async function for notification system - Convert recursive async function to synchronous with return values - Collect all status changes first, then process them asynchronously - Resolves Rust compiler error E0733 for recursive async functions - Maintains same functionality without boxing requirement - Verified with full workspace build matching NixOS configuration --- agent/src/simple_agent.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/agent/src/simple_agent.rs b/agent/src/simple_agent.rs index b4ee409..c47d440 100644 --- a/agent/src/simple_agent.rs +++ b/agent/src/simple_agent.rs @@ -169,30 +169,37 @@ impl SimpleAgent { async fn scan_for_status_changes(&mut self, data: &serde_json::Value, agent_name: &str) { // Recursively scan JSON for any field ending in "_status" - self.scan_object_for_status(data, agent_name, "").await; + let status_changes = self.scan_object_for_status(data, agent_name, ""); + + // Process all found status changes + for (component, metric, status, description) in status_changes { + if let Some(change) = self.notification_manager.update_status_with_details(&component, &metric, &status, Some(description)) { + info!("Status change: {}.{} {} -> {}", component, metric, change.old_status, change.new_status); + self.notification_manager.send_notification(change).await; + } + } } - async fn scan_object_for_status(&mut self, value: &serde_json::Value, agent_name: &str, path: &str) { + fn scan_object_for_status(&mut self, value: &serde_json::Value, agent_name: &str, path: &str) -> Vec<(String, String, String, String)> { + let mut status_changes = Vec::new(); + match value { serde_json::Value::Object(obj) => { for (key, val) in obj { let current_path = if path.is_empty() { key.clone() } else { format!("{}.{}", path, key) }; if key.ends_with("_status") && val.is_string() { - // Found a status field - check for changes + // Found a status field - collect for processing if let Some(status) = val.as_str() { let component = agent_name.to_lowercase(); let metric = key.trim_end_matches("_status"); let description = format!("Agent: {}, Component: {}, Source: {}", agent_name, component, current_path); - - if let Some(change) = self.notification_manager.update_status_with_details(&component, metric, status, Some(description)) { - info!("Status change: {} {} -> {}", current_path, change.old_status, change.new_status); - self.notification_manager.send_notification(change).await; - } + status_changes.push((component, metric.to_string(), status.to_string(), description)); } } else { // Recursively scan nested objects - self.scan_object_for_status(val, agent_name, ¤t_path).await; + let mut nested_changes = self.scan_object_for_status(val, agent_name, ¤t_path); + status_changes.append(&mut nested_changes); } } } @@ -200,11 +207,14 @@ impl SimpleAgent { // Scan array elements for individual item status tracking for (index, item) in arr.iter().enumerate() { let item_path = format!("{}[{}]", path, index); - self.scan_object_for_status(item, agent_name, &item_path).await; + let mut item_changes = self.scan_object_for_status(item, agent_name, &item_path); + status_changes.append(&mut item_changes); } } _ => {} } + + status_changes } } \ No newline at end of file