stackless_daemon/
state.rs1use std::collections::BTreeMap;
8use std::sync::RwLock;
9
10use stackless_core::process::ProcessStamp;
11use stackless_core::types::{DnsName, ProxyHost, TcpPort};
12
13use crate::rpc::{Route, SupervisedProcess};
14
15#[derive(Debug, Default)]
16pub struct DaemonState {
17 routes: RwLock<BTreeMap<ProxyHost, TcpPort>>,
19 supervised: RwLock<BTreeMap<(DnsName, DnsName), ProcessStamp>>,
21}
22
23impl DaemonState {
24 pub fn route_set(&self, host: ProxyHost, port: TcpPort) {
25 if let Ok(mut routes) = self.routes.write() {
26 routes.insert(host, port);
27 }
28 }
29
30 pub fn route_delete(&self, host: &ProxyHost) {
31 if let Ok(mut routes) = self.routes.write() {
32 routes.remove(host);
33 }
34 }
35
36 pub fn route_lookup(&self, host: &str) -> Option<TcpPort> {
37 let key = ProxyHost::try_new(host).ok()?;
38 self.routes.read().ok()?.get(&key).copied()
39 }
40
41 pub fn routes(&self) -> Vec<Route> {
42 self.routes
43 .read()
44 .map(|routes| {
45 routes
46 .iter()
47 .map(|(host, port)| Route {
48 host: host.clone(),
49 port: *port,
50 })
51 .collect()
52 })
53 .unwrap_or_default()
54 }
55
56 pub fn supervise(&self, instance: DnsName, service: DnsName, stamp: ProcessStamp) {
57 if let Ok(mut map) = self.supervised.write() {
58 map.insert((instance, service), stamp);
59 }
60 }
61
62 pub fn forget(&self, instance: &str) {
63 let Ok(instance_name) = DnsName::try_new(instance) else {
64 return;
65 };
66 if let Ok(mut map) = self.supervised.write() {
67 map.retain(|(i, _), _| i != &instance_name);
68 }
69 if let Ok(mut routes) = self.routes.write() {
70 routes.retain(|host, _| {
71 host.as_str() != format!("{instance}.localhost")
72 && !host.as_str().ends_with(&format!(".{instance}.localhost"))
73 });
74 }
75 }
76
77 pub fn instance_processes(&self, instance: &str) -> Vec<SupervisedProcess> {
80 let Ok(instance_name) = DnsName::try_new(instance) else {
81 return Vec::new();
82 };
83 self.supervised
84 .read()
85 .map(|map| {
86 map.iter()
87 .filter(|((i, _), _)| i == &instance_name)
88 .map(|((i, s), stamp)| SupervisedProcess {
89 instance: i.clone(),
90 service: s.clone(),
91 pid: stamp.pid,
92 start_time: stamp.start_time,
93 alive: stamp.is_alive(),
94 })
95 .collect()
96 })
97 .unwrap_or_default()
98 }
99}