vine_core/
app.rs

1use std::sync::Arc;
2use std::time::Instant;
3
4use log::{debug, info, warn};
5
6use crate::context::context::Context;
7use crate::core::Error;
8use crate::core::runner::Runner;
9
10pub struct App {
11    context: Arc<Context>,
12}
13
14impl Default for App {
15    fn default() -> Self {
16        App {
17            context: Arc::new(Context::new("root")),
18        }
19    }
20}
21
22impl App {
23    pub fn get_context(&self) -> &Context {
24        &self.context
25    }
26
27    pub fn add_context(&self, context: Context) {
28        self.context.add_context(context);
29    }
30
31    pub async fn exec(&self) -> Result<(), Error> {
32        let timer = Instant::now();
33        
34        info!("starting application");
35        self.context.init_contexts()?;
36
37        let mut runners = self.context.get_beans::<dyn Runner + Send + Sync>()?;
38        debug!("starting {} runners", runners.len());
39
40        let mut handles = Vec::new();
41        while let Some(r) = runners.pop() {
42            let runner = r.clone();
43            let name = runner.name().to_string();
44            
45            debug!("starting runner {}", r.name());
46            handles.push(tokio::spawn(async move {
47                let result = runner.run().await;
48                (name, result)
49            }));
50            debug!("runner {} has been started in {} micros", r.name(), timer.elapsed().as_micros());
51        }
52        info!("started in {} micros", timer.elapsed().as_micros());
53
54        let mut errors = Vec::new();
55        while let Some(runner_result) = handles.pop() {
56            let (name, result) = runner_result.await.map_err(|_| {
57               Error::from("failed to start runner")
58            })?;
59
60            if let Err(error) = result {
61                warn!("runner {} has been finished with error: {}", &name, &error);
62                errors.push(error);
63            }
64        }
65
66        info!("application finished {} micros", timer.elapsed().as_micros());
67        if errors.is_empty() {
68            Ok(())
69        } else {
70            Err(Error::from(errors.join("\n")))
71        }
72    }
73}