mecha10-runtime 0.6.2

Runtime supervisor for Mecha10 nodes - launching, monitoring, and lifecycle management
Documentation
//! Health checking infrastructure

use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock;

/// Health status of a node
#[derive(Clone, Debug, PartialEq)]
pub enum HealthStatus {
    /// Node is healthy and operating normally
    Healthy,

    /// Node is degraded but still functional
    Degraded { reason: String },

    /// Node is unhealthy and may need restart
    Unhealthy { reason: String },
}

impl HealthStatus {
    /// Check if status is healthy
    pub fn is_healthy(&self) -> bool {
        matches!(self, HealthStatus::Healthy)
    }

    /// Check if status is degraded
    pub fn is_degraded(&self) -> bool {
        matches!(self, HealthStatus::Degraded { .. })
    }

    /// Check if status is unhealthy
    pub fn is_unhealthy(&self) -> bool {
        matches!(self, HealthStatus::Unhealthy { .. })
    }

    /// Get reason if not healthy
    pub fn reason(&self) -> Option<&str> {
        match self {
            HealthStatus::Healthy => None,
            HealthStatus::Degraded { reason } => Some(reason),
            HealthStatus::Unhealthy { reason } => Some(reason),
        }
    }
}

/// Health checker for monitoring node health
pub struct HealthChecker {
    checks: Arc<RwLock<HashMap<String, HealthStatus>>>,
    interval: Duration,
}

impl HealthChecker {
    /// Create a new health checker with specified interval
    pub fn new(interval: Duration) -> Self {
        Self {
            checks: Arc::new(RwLock::new(HashMap::new())),
            interval,
        }
    }

    /// Register a node for health checking
    pub async fn register(&self, name: String, initial_status: HealthStatus) {
        let mut checks = self.checks.write().await;
        checks.insert(name, initial_status);
    }

    /// Update health status for a node
    pub async fn update(&self, name: &str, status: HealthStatus) {
        let mut checks = self.checks.write().await;
        checks.insert(name.to_string(), status);
    }

    /// Get health status for a specific node
    pub async fn check_one(&self, name: &str) -> Option<HealthStatus> {
        let checks = self.checks.read().await;
        checks.get(name).cloned()
    }

    /// Get health status for all nodes
    pub async fn check_all(&self) -> HashMap<String, HealthStatus> {
        let checks = self.checks.read().await;
        checks.clone()
    }

    /// Get the check interval
    pub fn interval(&self) -> Duration {
        self.interval
    }

    /// Remove a node from health checking
    pub async fn unregister(&self, name: &str) {
        let mut checks = self.checks.write().await;
        checks.remove(name);
    }
}