kumo_server_common/
start.rs1use crate::diagnostic_logging::LoggingConfig;
2use anyhow::Context;
3use config::RegisterFunc;
4use kumo_server_lifecycle::LifeCycle;
5use kumo_server_runtime::rt_spawn;
6use std::future::Future;
7use std::path::Path;
8pub struct StartConfig<'a> {
9 pub logging: LoggingConfig<'a>,
10 pub lua_funcs: &'a [RegisterFunc],
11 pub policy: &'a Path,
12}
13
14impl StartConfig<'_> {
15 pub async fn run<INIT, FINI>(
16 self,
17 init_future: INIT,
18 shutdown_future: FINI,
19 ) -> anyhow::Result<()>
20 where
21 INIT: Future<Output = anyhow::Result<()>> + Send + 'static,
22 FINI: Future<Output = ()> + Send + 'static,
23 {
24 self.logging.init()?;
25
26 rustls::crypto::aws_lc_rs::default_provider()
27 .install_default()
28 .map_err(|_| anyhow::anyhow!("failed to install default crypto provider"))?;
29
30 kumo_server_memory::setup_memory_limit().context("setup_memory_limit")?;
31
32 prometheus::register(Box::new(
33 tokio_metrics_collector::default_runtime_collector(),
34 ))
35 .context("failed to configure tokio-metrics-collector")?;
36
37 for &func in self.lua_funcs {
38 config::register(func);
39 }
40
41 config::set_policy_path(self.policy.to_path_buf())
42 .await
43 .with_context(|| format!("Error evaluating policy file {:?}", self.policy))?;
44
45 let mut life_cycle = LifeCycle::new();
46
47 let init_handle = rt_spawn("initialize", async move {
48 let mut error = None;
49 if let Err(err) = init_future.await {
50 let err = format!("{err:#}");
51 tracing::error!("problem initializing: {err}");
52 LifeCycle::request_shutdown().await;
53 error.replace(err);
54 }
55 tracing::info!("initialization complete");
59 error
60 })?;
61
62 life_cycle.wait_for_shutdown().await;
63
64 shutdown_future.await;
66
67 tracing::info!("Shutdown completed OK!");
68
69 if let Some(error) = init_handle.await? {
70 anyhow::bail!("Initialization raised an error: {error}");
71 }
72 Ok(())
73 }
74}