use std::sync::Arc;
use tokio::sync::RwLock;
use crate::channels::ComponentStatus;
use super::graph::ComponentGraph;
pub async fn wait_for_status(
graph: &Arc<RwLock<ComponentGraph>>,
component_id: &str,
target_statuses: &[ComponentStatus],
timeout: std::time::Duration,
) -> anyhow::Result<ComponentStatus> {
let deadline = tokio::time::Instant::now() + timeout;
let notify = {
let g = graph.read().await;
g.status_notifier()
};
loop {
let notified = notify.notified();
{
let g = graph.read().await;
if let Some(node) = g.get_component(component_id) {
if target_statuses.contains(&node.status) {
return Ok(node.status);
}
} else {
return Err(anyhow::anyhow!(
"Component '{component_id}' not found in graph"
));
}
}
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
if remaining.is_zero() {
return Err(anyhow::anyhow!(
"Timed out waiting for component '{component_id}' to reach {target_statuses:?}",
));
}
tokio::select! {
_ = notified => {
}
_ = tokio::time::sleep(remaining) => {
return Err(anyhow::anyhow!(
"Timed out waiting for component '{component_id}' to reach {target_statuses:?}",
));
}
}
}
}