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
|
use std::collections::HashMap;
use futures::stream::SelectAll;
use crate::{
service::{IntoService, ServiceConfig},
status::{NamedStatusStream, Receiver, StatusStream},
Status,
};
#[derive(Clone)]
pub struct AppState {
rx_map: HashMap<String, Receiver>,
indexes: Vec<String>,
}
impl AppState {
pub fn new(configs: Vec<ServiceConfig>) -> AppState {
let mut indexes = Vec::new();
let rx_map = configs
.into_iter()
.map(|ServiceConfig { name, kind }| {
indexes.push(name.clone());
tracing::debug!(name, "Added service");
let (tx, rx) = tokio::sync::watch::channel(Status::default());
tokio::spawn(kind.into_service(tx.clone()));
(name, rx)
})
.collect();
tracing::debug!(?indexes, "Finished spawning services");
AppState { rx_map, indexes }
}
pub fn status(&self, k: &str) -> Option<Status> {
self.rx_map.get(k).map(|rx| rx.borrow().clone())
}
pub fn statuses(&self) -> Vec<(String, Status)> {
self.indexes
.iter()
.cloned()
.map(|s| {
let status = self.status(&s).expect("Service was unexpectedly removed");
(s, status)
})
.collect()
}
pub fn stream(&self, k: &str) -> Option<StatusStream> {
self.rx_map.get(k).map(Into::into)
}
pub fn streams(&self) -> SelectAll<NamedStatusStream> {
futures::stream::select_all(self.rx_map.iter().map(Into::into))
}
}
|