1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! 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)
}
}