-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrunner.rs
More file actions
102 lines (85 loc) · 3.1 KB
/
Copy pathrunner.rs
File metadata and controls
102 lines (85 loc) · 3.1 KB
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
use crate::{
config::AdapterConfig,
store::AdapterStore,
traits::{LoadConfig, Server as AdapterServer},
};
use code0_flow::flow_definition::FlowUpdateService;
use std::sync::Arc;
use tokio::sync::broadcast;
use tonic::transport::Server;
use tonic_health::pb::health_server::HealthServer;
/// Context passed to adapter server implementations containing all shared resources
pub struct ServerContext<C: LoadConfig> {
pub server_config: Arc<C>,
pub adapter_config: Arc<AdapterConfig>,
pub adapter_store: Arc<AdapterStore>,
}
/// Main server runner that manages the complete adapter lifecycle
pub struct ServerRunner<C: LoadConfig> {
context: ServerContext<C>,
server: Box<dyn AdapterServer<C>>,
shutdown_sender: broadcast::Sender<()>,
}
impl<C: LoadConfig> ServerRunner<C> {
pub async fn new<S: AdapterServer<C>>(server: S) -> anyhow::Result<Self> {
code0_flow::flow_config::load_env_file();
let adapter_config = AdapterConfig::from_env();
let server_config = C::load();
let adapter_store = AdapterStore::from_url(
adapter_config.nats_url.clone(),
adapter_config.nats_bucket.clone(),
)
.await;
let context = ServerContext {
adapter_store: Arc::new(adapter_store),
adapter_config: Arc::new(adapter_config),
server_config: Arc::new(server_config),
};
let (shutdown_tx, _) = broadcast::channel(1);
Ok(Self {
context,
server: Box::new(server),
shutdown_sender: shutdown_tx,
})
}
pub async fn serve(mut self) -> anyhow::Result<()> {
let config = self.context.adapter_config.clone();
if !config.is_static() {
let definition_service = FlowUpdateService::from_url(
config.aquila_url.clone(),
config.definition_path.as_str(),
);
definition_service.send().await;
}
if config.with_health_service {
let health_service =
code0_flow::flow_health::HealthService::new(config.nats_url.clone());
let address = format!("{}:{}", config.grpc_host, config.grpc_port).parse()?;
tokio::spawn(async move {
let _ = Server::builder()
.add_service(HealthServer::new(health_service))
.serve(address)
.await;
});
log::info!(
"Health server started at {}:{}",
config.grpc_host,
config.grpc_port
);
}
self.server.init(&self.context).await?;
let mut rx = self.shutdown_sender.subscribe();
let context = self.context;
let mut server = self.server;
let handle = tokio::spawn(async move {
tokio::select! {
result = server.run(&context) => result,
_ = rx.recv() => server.shutdown(&context).await,
}
});
tokio::signal::ctrl_c().await?;
let _ = self.shutdown_sender.send(());
handle.await??;
Ok(())
}
}