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::error::{InitTlsProviderSnafu, Result};
19use cmd::options::GlobalOptions;
20use cmd::{cli, datanode, flownode, frontend, metasrv, standalone, App};
21use common_version::version;
22use servers::install_ring_crypto_provider;
23
24#[derive(Parser)]
25#[command(name = "greptime", author, version, long_version = version(), about)]
26#[command(propagate_version = true)]
27pub(crate) struct Command {
28    #[clap(subcommand)]
29    pub(crate) subcmd: SubCommand,
30
31    #[clap(flatten)]
32    pub(crate) global_options: GlobalOptions,
33}
34
35#[derive(Subcommand)]
36enum SubCommand {
37    /// Start datanode service.
38    #[clap(name = "datanode")]
39    Datanode(datanode::Command),
40
41    /// Start flownode service.
42    #[clap(name = "flownode")]
43    Flownode(flownode::Command),
44
45    /// Start frontend service.
46    #[clap(name = "frontend")]
47    Frontend(frontend::Command),
48
49    /// Start metasrv service.
50    #[clap(name = "metasrv")]
51    Metasrv(metasrv::Command),
52
53    /// Run greptimedb as a standalone service.
54    #[clap(name = "standalone")]
55    Standalone(standalone::Command),
56
57    /// Execute the cli tools for greptimedb.
58    #[clap(name = "cli")]
59    Cli(cli::Command),
60}
61
62#[cfg(not(windows))]
63#[global_allocator]
64static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
65
66#[cfg(debug_assertions)]
67fn main() -> Result<()> {
68    use snafu::ResultExt;
69    // Set the stack size to 8MB for the thread so it wouldn't overflow on large stack usage in debug mode
70    // see https://github.com/GreptimeTeam/greptimedb/pull/4317
71    // and https://github.com/rust-lang/rust/issues/34283
72    std::thread::Builder::new()
73        .name("main_spawn".to_string())
74        .stack_size(8 * 1024 * 1024)
75        .spawn(|| {
76            {
77                tokio::runtime::Builder::new_multi_thread()
78                    .thread_stack_size(8 * 1024 * 1024)
79                    .enable_all()
80                    .build()
81                    .expect("Failed building the Runtime")
82                    .block_on(main_body())
83            }
84        })
85        .context(cmd::error::SpawnThreadSnafu)?
86        .join()
87        .expect("Couldn't join on the associated thread")
88}
89
90#[cfg(not(debug_assertions))]
91#[tokio::main]
92async fn main() -> Result<()> {
93    main_body().await
94}
95
96async fn main_body() -> Result<()> {
97    setup_human_panic();
98    install_ring_crypto_provider().map_err(|msg| InitTlsProviderSnafu { msg }.build())?;
99    start(Command::parse()).await
100}
101
102async fn start(cli: Command) -> Result<()> {
103    match cli.subcmd {
104        SubCommand::Datanode(cmd) => {
105            cmd.build(cmd.load_options(&cli.global_options)?)
106                .await?
107                .run()
108                .await
109        }
110        SubCommand::Flownode(cmd) => {
111            cmd.build(cmd.load_options(&cli.global_options)?)
112                .await?
113                .run()
114                .await
115        }
116        SubCommand::Frontend(cmd) => {
117            cmd.build(cmd.load_options(&cli.global_options)?)
118                .await?
119                .run()
120                .await
121        }
122        SubCommand::Metasrv(cmd) => {
123            cmd.build(cmd.load_options(&cli.global_options)?)
124                .await?
125                .run()
126                .await
127        }
128        SubCommand::Standalone(cmd) => {
129            cmd.build(cmd.load_options(&cli.global_options)?)
130                .await?
131                .run()
132                .await
133        }
134        SubCommand::Cli(cmd) => {
135            cmd.build(cmd.load_options(&cli.global_options)?)
136                .await?
137                .run()
138                .await
139        }
140    }
141}
142
143fn setup_human_panic() {
144    human_panic::setup_panic!(
145        human_panic::Metadata::new("GreptimeDB", env!("CARGO_PKG_VERSION"))
146            .homepage("https://github.com/GreptimeTeam/greptimedb/discussions")
147    );
148
149    common_telemetry::set_panic_hook();
150}