greptime/
greptime.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![doc = include_str!("../../../../README.md")]
16
17use clap::{Parser, Subcommand};
18use cmd::datanode::builder::InstanceBuilder;
19use cmd::error::{InitTlsProviderSnafu, Result};
20use cmd::options::GlobalOptions;
21use cmd::{cli, datanode, flownode, frontend, metasrv, standalone, App};
22use common_base::Plugins;
23use common_version::version;
24use servers::install_ring_crypto_provider;
25
26#[derive(Parser)]
27#[command(name = "greptime", author, version, long_version = version(), about)]
28#[command(propagate_version = true)]
29pub(crate) struct Command {
30    #[clap(subcommand)]
31    pub(crate) subcmd: SubCommand,
32
33    #[clap(flatten)]
34    pub(crate) global_options: GlobalOptions,
35}
36
37#[derive(Subcommand)]
38enum SubCommand {
39    /// Start datanode service.
40    #[clap(name = "datanode")]
41    Datanode(datanode::Command),
42
43    /// Start flownode service.
44    #[clap(name = "flownode")]
45    Flownode(flownode::Command),
46
47    /// Start frontend service.
48    #[clap(name = "frontend")]
49    Frontend(frontend::Command),
50
51    /// Start metasrv service.
52    #[clap(name = "metasrv")]
53    Metasrv(metasrv::Command),
54
55    /// Run greptimedb as a standalone service.
56    #[clap(name = "standalone")]
57    Standalone(standalone::Command),
58
59    /// Execute the cli tools for greptimedb.
60    #[clap(name = "cli")]
61    Cli(cli::Command),
62}
63
64#[cfg(not(windows))]
65#[global_allocator]
66static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
67
68#[cfg(debug_assertions)]
69fn main() -> Result<()> {
70    use snafu::ResultExt;
71    // Set the stack size to 8MB for the thread so it wouldn't overflow on large stack usage in debug mode
72    // see https://github.com/GreptimeTeam/greptimedb/pull/4317
73    // and https://github.com/rust-lang/rust/issues/34283
74    std::thread::Builder::new()
75        .name("main_spawn".to_string())
76        .stack_size(8 * 1024 * 1024)
77        .spawn(|| {
78            {
79                tokio::runtime::Builder::new_multi_thread()
80                    .thread_stack_size(8 * 1024 * 1024)
81                    .enable_all()
82                    .build()
83                    .expect("Failed building the Runtime")
84                    .block_on(main_body())
85            }
86        })
87        .context(cmd::error::SpawnThreadSnafu)?
88        .join()
89        .expect("Couldn't join on the associated thread")
90}
91
92#[cfg(not(debug_assertions))]
93#[tokio::main]
94async fn main() -> Result<()> {
95    main_body().await
96}
97
98async fn main_body() -> Result<()> {
99    setup_human_panic();
100    install_ring_crypto_provider().map_err(|msg| InitTlsProviderSnafu { msg }.build())?;
101    start(Command::parse()).await
102}
103
104async fn start(cli: Command) -> Result<()> {
105    match cli.subcmd {
106        SubCommand::Datanode(cmd) => {
107            let opts = cmd.load_options(&cli.global_options)?;
108            let plugins = Plugins::new();
109            let builder = InstanceBuilder::try_new_with_init(opts, plugins).await?;
110            cmd.build_with(builder).await?.run().await
111        }
112        SubCommand::Flownode(cmd) => {
113            cmd.build(cmd.load_options(&cli.global_options)?)
114                .await?
115                .run()
116                .await
117        }
118        SubCommand::Frontend(cmd) => {
119            cmd.build(cmd.load_options(&cli.global_options)?)
120                .await?
121                .run()
122                .await
123        }
124        SubCommand::Metasrv(cmd) => {
125            cmd.build(cmd.load_options(&cli.global_options)?)
126                .await?
127                .run()
128                .await
129        }
130        SubCommand::Standalone(cmd) => {
131            cmd.build(cmd.load_options(&cli.global_options)?)
132                .await?
133                .run()
134                .await
135        }
136        SubCommand::Cli(cmd) => {
137            cmd.build(cmd.load_options(&cli.global_options)?)
138                .await?
139                .run()
140                .await
141        }
142    }
143}
144
145fn setup_human_panic() {
146    human_panic::setup_panic!(
147        human_panic::Metadata::new("GreptimeDB", env!("CARGO_PKG_VERSION"))
148            .homepage("https://github.com/GreptimeTeam/greptimedb/discussions")
149    );
150
151    common_telemetry::set_panic_hook();
152}