tendermint_light_node/
application.rs

1//! LightNode Abscissa Application
2
3use crate::{commands::LightNodeCmd, config::LightNodeConfig};
4use abscissa_core::{
5    application::{self, AppCell},
6    config, trace, Application, EntryPoint, FrameworkError, StandardPaths,
7};
8
9/// Application state
10pub static APPLICATION: AppCell<LightNodeApp> = AppCell::new();
11
12/// Obtain a read-only (multi-reader) lock on the application state.
13///
14/// Panics if the application state has not been initialized.
15pub fn app_reader() -> application::lock::Reader<LightNodeApp> {
16    APPLICATION.read()
17}
18
19/// Obtain an exclusive mutable lock on the application state.
20pub fn app_writer() -> application::lock::Writer<LightNodeApp> {
21    APPLICATION.write()
22}
23
24/// Obtain a read-only (multi-reader) lock on the application configuration.
25///
26/// Panics if the application configuration has not been loaded.
27pub fn app_config() -> config::Reader<LightNodeApp> {
28    config::Reader::new(&APPLICATION)
29}
30
31/// LightNode Application
32#[derive(Debug)]
33pub struct LightNodeApp {
34    /// Application configuration.
35    config: Option<LightNodeConfig>,
36
37    /// Application state.
38    state: application::State<Self>,
39}
40
41/// Initialize a new application instance.
42///
43/// By default no configuration is loaded, and the framework state is
44/// initialized to a default, empty state (no components, threads, etc).
45impl Default for LightNodeApp {
46    fn default() -> Self {
47        Self {
48            config: None,
49            state: application::State::default(),
50        }
51    }
52}
53
54impl Application for LightNodeApp {
55    /// Entrypoint command for this application.
56    type Cmd = EntryPoint<LightNodeCmd>;
57
58    /// Application configuration.
59    type Cfg = LightNodeConfig;
60
61    /// Paths to resources within the application.
62    type Paths = StandardPaths;
63
64    /// Accessor for application configuration.
65    fn config(&self) -> &LightNodeConfig {
66        self.config.as_ref().expect("config not loaded")
67    }
68
69    /// Borrow the application state immutably.
70    fn state(&self) -> &application::State<Self> {
71        &self.state
72    }
73
74    /// Borrow the application state mutably.
75    fn state_mut(&mut self) -> &mut application::State<Self> {
76        &mut self.state
77    }
78
79    /// Register all components used by this application.
80    ///
81    /// If you would like to add additional components to your application
82    /// beyond the default ones provided by the framework, this is the place
83    /// to do so.
84    fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> {
85        let components = self.framework_components(command)?;
86        self.state.components.register(components)
87    }
88
89    /// Post-configuration lifecycle callback.
90    ///
91    /// Called regardless of whether config is loaded to indicate this is the
92    /// time in app lifecycle when configuration would be loaded if
93    /// possible.
94    fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> {
95        // Configure components
96        self.state.components.after_config(&config)?;
97        self.config = Some(config);
98        Ok(())
99    }
100
101    /// Get tracing configuration from command-line options
102    fn tracing_config(&self, command: &EntryPoint<LightNodeCmd>) -> trace::Config {
103        if command.verbose {
104            trace::Config::verbose()
105        } else {
106            trace::Config::default()
107        }
108    }
109}