Skip to main content

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