1#![feature(assert_matches, let_chains)]
16
17use async_trait::async_trait;
18use common_telemetry::{error, info};
19
20use crate::error::Result;
21
22pub mod cli;
23pub mod datanode;
24pub mod error;
25pub mod flownode;
26pub mod frontend;
27pub mod metasrv;
28pub mod options;
29pub mod standalone;
30
31lazy_static::lazy_static! {
32 static ref APP_VERSION: prometheus::IntGaugeVec =
33 prometheus::register_int_gauge_vec!("greptime_app_version", "app version", &["version", "short_version", "app"]).unwrap();
34}
35
36#[cfg(unix)]
38async fn start_wait_for_close_signal() -> std::io::Result<()> {
39 use tokio::signal::unix::{signal, SignalKind};
40 let mut sigint = signal(SignalKind::interrupt())?;
41 let mut sigterm = signal(SignalKind::terminate())?;
42
43 tokio::select! {
44 _ = sigint.recv() => {
45 info!("Received SIGINT, shutting down");
46 }
47 _ = sigterm.recv() => {
48 info!("Received SIGTERM, shutting down");
49 }
50 }
51
52 Ok(())
53}
54
55#[cfg(not(unix))]
57async fn start_wait_for_close_signal() -> std::io::Result<()> {
58 tokio::signal::ctrl_c().await
59}
60
61#[async_trait]
62pub trait App: Send {
63 fn name(&self) -> &str;
64
65 async fn pre_start(&mut self) -> Result<()> {
67 Ok(())
68 }
69
70 async fn start(&mut self) -> Result<()>;
71
72 fn wait_signal(&self) -> bool {
74 true
75 }
76
77 async fn stop(&mut self) -> Result<()>;
78
79 async fn run(&mut self) -> Result<()> {
80 info!("Starting app: {}", self.name());
81
82 self.pre_start().await?;
83
84 self.start().await?;
85
86 if self.wait_signal() {
87 if let Err(e) = start_wait_for_close_signal().await {
88 error!(e; "Failed to listen for close signal");
89 }
93 }
94
95 self.stop().await?;
96 info!("Goodbye!");
97 Ok(())
98 }
99}
100
101pub fn log_versions(version: &str, short_version: &str, app: &str) {
106 APP_VERSION
108 .with_label_values(&[env!("CARGO_PKG_VERSION"), short_version, app])
109 .inc();
110
111 info!("GreptimeDB version: {}", version);
113
114 log_env_flags();
115}
116
117fn log_env_flags() {
118 info!("command line arguments");
119 for argument in std::env::args() {
120 info!("argument: {}", argument);
121 }
122}