mecha10-cli 0.7.0

Mecha10 CLI tool
Documentation
//! Status, stop/restart, and cleanup operations for `ProcessService`

use super::ProcessService;
use anyhow::Result;
use std::collections::HashMap;

impl ProcessService {
    /// Get status of all processes
    ///
    /// Returns a HashMap mapping process names to status strings
    pub fn get_status(&mut self) -> HashMap<String, String> {
        use mecha10_runtime::ProcessStatus;

        self.manager
            .status_all()
            .into_iter()
            .map(|(name, status)| {
                let status_str = match status {
                    ProcessStatus::Running => "running".to_string(),
                    ProcessStatus::Exited(code) => format!("exited (code: {})", code),
                    ProcessStatus::Error => "error".to_string(),
                };
                (name, status_str)
            })
            .collect()
    }

    /// Stop a specific process by name
    ///
    /// # Arguments
    ///
    /// * `name` - Name of the process to stop
    ///
    /// # Errors
    ///
    /// Returns an error if the process is not found
    ///
    /// Note: This uses a default 10-second timeout for graceful shutdown.
    /// Use stop_with_timeout() for custom timeout.
    pub fn stop(&mut self, name: &str) -> Result<()> {
        self.manager.stop_graceful(name, std::time::Duration::from_secs(10))
    }

    /// Stop a process with timeout for graceful shutdown
    ///
    /// Tries graceful shutdown (SIGTERM on Unix), then force kills after timeout
    ///
    /// # Arguments
    ///
    /// * `name` - Name of the process to stop
    /// * `timeout` - How long to wait for graceful shutdown
    ///
    /// # Errors
    ///
    /// Returns an error if process not found or cannot be stopped
    pub fn stop_with_timeout(&mut self, name: &str, timeout: std::time::Duration) -> Result<()> {
        self.manager.stop_graceful(name, timeout)
    }

    /// * `name` - Name of the process to kill
    pub fn force_kill(&mut self, name: &str) -> Result<()> {
        self.manager.force_kill(name)
    }

    /// Stop all processes gracefully in dependency order
    ///
    /// This delegates to the runtime's ProcessManager which handles:
    /// - Dependency-based shutdown ordering
    /// - Graceful shutdown with timeout
    /// - Force kill fallback
    pub fn cleanup(&mut self) {
        self.manager.shutdown_all();
    }

    /// * `name` - Name of the process to check
    pub fn is_running(&mut self, name: &str) -> bool {
        self.manager.is_running(name)
    }

    /// Restart a specific process
    ///
    /// Stops the process if running and starts it again
    ///
    /// # Arguments
    ///
    /// * `name` - Name of the process
    /// * `binary_path` - Path to the binary
    /// * `args` - Command-line arguments
    pub fn restart(&mut self, name: &str, binary_path: &str, args: &[&str]) -> Result<u32> {
        if self.is_running(name) {
            self.stop(name)?;
            std::thread::sleep(std::time::Duration::from_millis(100));
        }

        self.spawn_node(name, binary_path, args)
    }

    /// Restart all processes
    ///
    /// # Arguments
    ///
    /// * `nodes` - Vec of (name, binary_path, args) tuples
    pub fn restart_all(&mut self, nodes: Vec<(&str, &str, Vec<&str>)>) -> Result<HashMap<String, u32>> {
        self.cleanup();

        std::thread::sleep(std::time::Duration::from_millis(500));

        self.spawn_nodes(nodes)
    }
}