Skip to content

Commit

Permalink
refactor: remove Options struct and make the start() clean
Browse files Browse the repository at this point in the history
  • Loading branch information
zyy17 committed May 18, 2024
1 parent 010438d commit ad86eab
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 261 deletions.
105 changes: 34 additions & 71 deletions src/cmd/src/bin/greptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@

#![doc = include_str!("../../../../README.md")]

use std::fmt;

use clap::{Parser, Subcommand};
use cmd::error::Result;
use cmd::options::{GlobalOptions, Options};
use cmd::options::GlobalOptions;
use cmd::{cli, datanode, frontend, log_versions, metasrv, standalone, App};
use common_version::{short_version, version};

Expand Down Expand Up @@ -56,85 +54,50 @@ enum SubCommand {
Cli(cli::Command),
}

impl SubCommand {
async fn build(self, opts: Options) -> Result<Box<dyn App>> {
let app: Box<dyn App> = match (self, opts) {
(SubCommand::Datanode(cmd), Options::Datanode(dn_opts)) => {
let app = cmd.build(*dn_opts).await?;
Box::new(app) as _
}
(SubCommand::Frontend(cmd), Options::Frontend(fe_opts)) => {
let app = cmd.build(*fe_opts).await?;
Box::new(app) as _
}
(SubCommand::Metasrv(cmd), Options::Metasrv(meta_opts)) => {
let app = cmd.build(*meta_opts).await?;
Box::new(app) as _
}
(SubCommand::Standalone(cmd), Options::Standalone(opts)) => {
let app = cmd.build(*opts).await?;
Box::new(app) as _
}
(SubCommand::Cli(cmd), Options::Cli(_)) => {
let app = cmd.build().await?;
Box::new(app) as _
}

_ => unreachable!(),
};
Ok(app)
}

fn load_options(&self, global_options: &GlobalOptions) -> Result<Options> {
match self {
SubCommand::Datanode(cmd) => cmd.load_options(global_options),
SubCommand::Frontend(cmd) => cmd.load_options(global_options),
SubCommand::Metasrv(cmd) => cmd.load_options(global_options),
SubCommand::Standalone(cmd) => cmd.load_options(global_options),
SubCommand::Cli(cmd) => cmd.load_options(global_options),
}
}
}

impl fmt::Display for SubCommand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SubCommand::Datanode(..) => write!(f, "greptime-datanode"),
SubCommand::Frontend(..) => write!(f, "greptime-frontend"),
SubCommand::Metasrv(..) => write!(f, "greptime-metasrv"),
SubCommand::Standalone(..) => write!(f, "greptime-standalone"),
SubCommand::Cli(_) => write!(f, "greptime-cli"),
}
}
}

#[cfg(not(windows))]
#[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

#[tokio::main]
async fn main() -> Result<()> {
setup_human_panic();
log_versions(version!(), short_version!());
start(Command::parse()).await
}

async fn start(cli: Command) -> Result<()> {
let subcmd = cli.subcmd;

let app_name = subcmd.to_string();

let opts = subcmd.load_options(&cli.global_options)?;

let _guard = common_telemetry::init_global_logging(
&app_name,
opts.logging_options(),
&cli.global_options.tracing_options(),
opts.node_id(),
);

log_versions(version!(), short_version!());

subcmd.build(opts).await?.run().await
match cli.subcmd {
SubCommand::Datanode(cmd) => {
cmd.build(cmd.load_options(&cli.global_options)?)
.await?
.run()
.await
}
SubCommand::Frontend(cmd) => {
cmd.build(cmd.load_options(&cli.global_options)?)
.await?
.run()
.await
}
SubCommand::Metasrv(cmd) => {
cmd.build(cmd.load_options(&cli.global_options)?)
.await?
.run()
.await
}
SubCommand::Standalone(cmd) => {
cmd.build(cmd.load_options(&cli.global_options)?)
.await?
.run()
.await
}
SubCommand::Cli(cmd) => {
cmd.build(cmd.load_options(&cli.global_options)?)
.await?
.run()
.await
}
}
}

fn setup_human_panic() {
Expand Down
23 changes: 16 additions & 7 deletions src/cmd/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ mod upgrade;
use async_trait::async_trait;
use bench::BenchTableMetadataCommand;
use clap::Parser;
use common_telemetry::logging::LoggingOptions;
use common_telemetry::logging::{LoggingOptions, TracingOptions};
// pub use repl::Repl;
use upgrade::UpgradeCommand;

use self::export::ExportCommand;
use crate::error::Result;
use crate::options::{GlobalOptions, Options};
use crate::options::GlobalOptions;
use crate::App;

pub const APP_NAME: &str = "greptime-cli";

#[async_trait]
pub trait Tool: Send + Sync {
async fn do_work(&self) -> Result<()>;
Expand All @@ -57,7 +59,7 @@ impl Instance {
#[async_trait]
impl App for Instance {
fn name(&self) -> &str {
"greptime-cli"
APP_NAME
}

async fn start(&mut self) -> Result<()> {
Expand All @@ -80,11 +82,18 @@ pub struct Command {
}

impl Command {
pub async fn build(self) -> Result<Instance> {
pub async fn build(&self, opts: LoggingOptions) -> Result<Instance> {
let _guard = common_telemetry::init_global_logging(
APP_NAME,
&opts,
&TracingOptions::default(),
None,
);

self.cmd.build().await
}

pub fn load_options(&self, global_options: &GlobalOptions) -> Result<Options> {
pub fn load_options(&self, global_options: &GlobalOptions) -> Result<LoggingOptions> {
let mut logging_opts = LoggingOptions::default();

if let Some(dir) = &global_options.log_dir {
Expand All @@ -93,7 +102,7 @@ impl Command {

logging_opts.level.clone_from(&global_options.log_level);

Ok(Options::Cli(Box::new(logging_opts)))
Ok(logging_opts)
}
}

Expand All @@ -106,7 +115,7 @@ enum SubCommand {
}

impl SubCommand {
async fn build(self) -> Result<Instance> {
async fn build(&self) -> Result<Instance> {
match self {
// SubCommand::Attach(cmd) => cmd.build().await,
SubCommand::Upgrade(cmd) => cmd.build().await,
Expand Down
72 changes: 34 additions & 38 deletions src/cmd/src/datanode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ use snafu::{OptionExt, ResultExt};
use crate::error::{
LoadLayeredConfigSnafu, MissingConfigSnafu, Result, ShutdownDatanodeSnafu, StartDatanodeSnafu,
};
use crate::options::{GlobalOptions, Options};
use crate::options::GlobalOptions;
use crate::App;

pub const APP_NAME: &str = "greptime-datanode";

pub struct Instance {
datanode: Datanode,
}
Expand All @@ -56,7 +58,7 @@ impl Instance {
#[async_trait]
impl App for Instance {
fn name(&self) -> &str {
"greptime-datanode"
APP_NAME
}

async fn start(&mut self) -> Result<()> {
Expand All @@ -82,11 +84,11 @@ pub struct Command {
}

impl Command {
pub async fn build(self, opts: DatanodeOptions) -> Result<Instance> {
pub async fn build(&self, opts: DatanodeOptions) -> Result<Instance> {
self.subcmd.build(opts).await
}

pub fn load_options(&self, global_options: &GlobalOptions) -> Result<Options> {
pub fn load_options(&self, global_options: &GlobalOptions) -> Result<DatanodeOptions> {
self.subcmd.load_options(global_options)
}
}
Expand All @@ -97,13 +99,13 @@ enum SubCommand {
}

impl SubCommand {
async fn build(self, opts: DatanodeOptions) -> Result<Instance> {
async fn build(&self, opts: DatanodeOptions) -> Result<Instance> {
match self {
SubCommand::Start(cmd) => cmd.build(opts).await,
}
}

fn load_options(&self, global_options: &GlobalOptions) -> Result<Options> {
fn load_options(&self, global_options: &GlobalOptions) -> Result<DatanodeOptions> {
match self {
SubCommand::Start(cmd) => cmd.load_options(global_options),
}
Expand Down Expand Up @@ -135,17 +137,15 @@ struct StartCommand {
}

impl StartCommand {
fn load_options(&self, global_options: &GlobalOptions) -> Result<Options> {
Ok(Options::Datanode(Box::new(
self.merge_with_cli_options(
global_options,
DatanodeOptions::load_layered_options(
self.config_file.as_deref(),
self.env_prefix.as_ref(),
)
.context(LoadLayeredConfigSnafu)?,
)?,
)))
fn load_options(&self, global_options: &GlobalOptions) -> Result<DatanodeOptions> {
self.merge_with_cli_options(
global_options,
DatanodeOptions::load_layered_options(
self.config_file.as_deref(),
self.env_prefix.as_ref(),
)
.context(LoadLayeredConfigSnafu)?,
)
}

// The precedence order is: cli > config file > environment variables > default values.
Expand Down Expand Up @@ -226,7 +226,14 @@ impl StartCommand {
Ok(opts)
}

async fn build(self, mut opts: DatanodeOptions) -> Result<Instance> {
async fn build(&self, mut opts: DatanodeOptions) -> Result<Instance> {
let _guard = common_telemetry::init_global_logging(
APP_NAME,
&opts.logging,
&opts.tracing,
opts.node_id.map(|x| x.to_string()),
);

let plugins = plugins::setup_datanode_plugins(&mut opts)
.await
.context(StartDatanodeSnafu)?;
Expand Down Expand Up @@ -337,10 +344,7 @@ mod tests {
..Default::default()
};

let Options::Datanode(options) = cmd.load_options(&GlobalOptions::default()).unwrap()
else {
unreachable!()
};
let options = cmd.load_options(&GlobalOptions::default()).unwrap();

assert_eq!("127.0.0.1:3001".to_string(), options.rpc_addr);
assert_eq!(Some(42), options.node_id);
Expand Down Expand Up @@ -399,23 +403,19 @@ mod tests {

#[test]
fn test_try_from_cmd() {
if let Options::Datanode(opt) = StartCommand::default()
let opt = StartCommand::default()
.load_options(&GlobalOptions::default())
.unwrap()
{
assert_eq!(Mode::Standalone, opt.mode)
}
.unwrap();
assert_eq!(Mode::Standalone, opt.mode);

if let Options::Datanode(opt) = (StartCommand {
let opt = (StartCommand {
node_id: Some(42),
metasrv_addrs: Some(vec!["127.0.0.1:3002".to_string()]),
..Default::default()
})
.load_options(&GlobalOptions::default())
.unwrap()
{
assert_eq!(Mode::Distributed, opt.mode)
}
.unwrap();
assert_eq!(Mode::Distributed, opt.mode);

assert!((StartCommand {
metasrv_addrs: Some(vec!["127.0.0.1:3002".to_string()]),
Expand Down Expand Up @@ -447,7 +447,7 @@ mod tests {
})
.unwrap();

let logging_opt = options.logging_options();
let logging_opt = options.logging;
assert_eq!("/tmp/greptimedb/test/logs", logging_opt.dir);
assert_eq!("debug", logging_opt.level.as_ref().unwrap());
}
Expand Down Expand Up @@ -527,11 +527,7 @@ mod tests {
..Default::default()
};

let Options::Datanode(opts) =
command.load_options(&GlobalOptions::default()).unwrap()
else {
unreachable!()
};
let opts = command.load_options(&GlobalOptions::default()).unwrap();

// Should be read from env, env > default values.
let DatanodeWalConfig::RaftEngine(raft_engine_config) = opts.wal else {
Expand Down
Loading

0 comments on commit ad86eab

Please sign in to comment.