mecha10_runtime/
launcher.rs1use crate::node::NodeRunner;
4use crate::supervisor::{NodeHandle, Supervisor};
5use anyhow::Result;
6use std::collections::HashMap;
7use std::sync::Arc;
8use tokio::sync::RwLock;
9
10pub type NodeFactory = Box<dyn Fn() -> Box<dyn NodeRunner> + Send + Sync>;
12
13pub struct Launcher {
15 supervisor: Arc<Supervisor>,
16 factories: Arc<RwLock<HashMap<String, NodeFactory>>>,
17 running_nodes: Arc<RwLock<HashMap<String, NodeHandle>>>,
18}
19
20impl Launcher {
21 pub fn new(supervisor: Arc<Supervisor>) -> Self {
23 Self {
24 supervisor,
25 factories: Arc::new(RwLock::new(HashMap::new())),
26 running_nodes: Arc::new(RwLock::new(HashMap::new())),
27 }
28 }
29
30 pub async fn register<F>(&self, node_type: String, factory: F)
32 where
33 F: Fn() -> Box<dyn NodeRunner> + Send + Sync + 'static,
34 {
35 let mut factories = self.factories.write().await;
36 factories.insert(node_type, Box::new(factory));
37 }
38
39 pub async fn launch(&self, node_type: &str) -> Result<String> {
41 let factories = self.factories.read().await;
42 let factory = factories
43 .get(node_type)
44 .ok_or_else(|| anyhow::anyhow!("Unknown node type: {}", node_type))?;
45
46 let node = factory();
47 let node_name = node.name().to_string();
48
49 let running = self.running_nodes.read().await;
51 if running.contains_key(&node_name) {
52 anyhow::bail!("Node already running: {}", node_name);
53 }
54 drop(running);
55
56 let handle = self.supervisor.launch_node(node);
58 let name = handle.name().to_string();
59
60 let mut running = self.running_nodes.write().await;
61 running.insert(name.clone(), handle);
62
63 Ok(name)
64 }
65
66 pub async fn stop(&self, node_name: &str) -> Result<()> {
68 let mut running = self.running_nodes.write().await;
69 let handle = running
70 .remove(node_name)
71 .ok_or_else(|| anyhow::anyhow!("Node not running: {}", node_name))?;
72
73 handle.abort();
74 Ok(())
75 }
76
77 pub async fn list_running(&self) -> Vec<String> {
79 let running = self.running_nodes.read().await;
80 running.keys().cloned().collect()
81 }
82
83 pub async fn is_running(&self, node_name: &str) -> bool {
85 let running = self.running_nodes.read().await;
86 running.contains_key(node_name)
87 }
88
89 pub async fn list_types(&self) -> Vec<String> {
91 let factories = self.factories.read().await;
92 factories.keys().cloned().collect()
93 }
94}