From 2f3b32952d3fce682075ce8d9cc181ee00bbe8f0 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Thu, 16 Apr 2020 18:10:30 +0800 Subject: [PATCH] feat: prof command support specify target --- Cargo.lock | 1 + ckb-bin/Cargo.toml | 1 + ckb-bin/src/subcommand/prof.rs | 79 ++++++++++++++++++++++------------ util/app-config/src/args.rs | 1 + util/app-config/src/cli.rs | 12 ++++-- util/app-config/src/lib.rs | 2 + 6 files changed, 64 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf5d5f9707..2df23430f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,6 +378,7 @@ dependencies = [ "ctrlc", "serde", "serde_plain", + "tempfile", "toml", ] diff --git a/ckb-bin/Cargo.toml b/ckb-bin/Cargo.toml index 502c28c695..ffb7307592 100644 --- a/ckb-bin/Cargo.toml +++ b/ckb-bin/Cargo.toml @@ -32,6 +32,7 @@ ckb-build-info = { path = "../util/build-info" } ckb-memory-tracker = { path = "../util/memory-tracker" } ckb-verification = { path = "../verification" } base64 = "0.10.1" +tempfile = "3.0" [features] deadlock_detection = ["ckb-util/deadlock_detection"] diff --git a/ckb-bin/src/subcommand/prof.rs b/ckb-bin/src/subcommand/prof.rs index 040793966f..5bb0dd4eb5 100644 --- a/ckb-bin/src/subcommand/prof.rs +++ b/ckb-bin/src/subcommand/prof.rs @@ -5,6 +5,7 @@ use ckb_logger::info; use ckb_shared::shared::{Shared, SharedBuilder}; use ckb_store::ChainStore; use std::sync::Arc; +use tempfile; pub fn profile(args: ProfArgs) -> Result<(), ExitCode> { let (shared, _table) = SharedBuilder::with_db_config(&args.config.db) @@ -16,35 +17,57 @@ pub fn profile(args: ProfArgs) -> Result<(), ExitCode> { ExitCode::Failure })?; - let (tmp_shared, table) = SharedBuilder::default() - .consensus(args.consensus) - .tx_pool_config(args.config.tx_pool) - .build() - .map_err(|err| { - eprintln!("Prof error: {:?}", err); - ExitCode::Failure - })?; + if !args.tmp_target.is_dir() { + eprintln!( + "Prof error: {:?}", + "The specified path does not exist or not directory" + ); + return Err(ExitCode::Failure); + } + let tmp_db_dir = tempfile::tempdir_in(args.tmp_target).map_err(|err| { + eprintln!("Prof error: {:?}", err); + ExitCode::Failure + })?; + { + let mut tmp_db_config = args.config.db.clone(); + tmp_db_config.path = tmp_db_dir.path().to_path_buf(); + + let (tmp_shared, table) = SharedBuilder::with_db_config(&tmp_db_config) + .consensus(args.consensus) + .tx_pool_config(args.config.tx_pool) + .build() + .map_err(|err| { + eprintln!("Prof error: {:?}", err); + ExitCode::Failure + })?; + + let from = std::cmp::max(1, args.from); + let to = std::cmp::min(shared.snapshot().tip_number(), args.to); + let chain = ChainService::new(tmp_shared, table); + let chain_controller = chain.start(Some("chain")); + profile_block_process( + shared.clone(), + chain_controller.clone(), + 1, + std::cmp::max(1, from.saturating_sub(1)), + ); + info!("start profling, re-process blocks {}..{}:", from, to); + let now = std::time::Instant::now(); + let tx_count = profile_block_process(shared, chain_controller, from, to); + let duration = now.elapsed(); + info!( + "end profling, duration {:?} txs {} tps {}", + duration, + tx_count, + tx_count as u64 / duration.as_secs() + ); + } + + tmp_db_dir.close().map_err(|err| { + eprintln!("Prof error: {:?}", err); + ExitCode::Failure + })?; - let from = std::cmp::max(1, args.from); - let to = std::cmp::min(shared.snapshot().tip_number(), args.to); - let chain = ChainService::new(tmp_shared, table); - let chain_controller = chain.start(Some("chain")); - profile_block_process( - shared.clone(), - chain_controller.clone(), - 1, - std::cmp::max(1, from.saturating_sub(1)), - ); - info!("start profling, re-process blocks {}..{}:", from, to); - let now = std::time::Instant::now(); - let tx_count = profile_block_process(shared, chain_controller, from, to); - let duration = now.elapsed(); - info!( - "end profling, duration {:?} txs {} tps {}", - duration, - tx_count, - tx_count as u64 / duration.as_secs() - ); Ok(()) } diff --git a/util/app-config/src/args.rs b/util/app-config/src/args.rs index 8f8bc2055c..1124c6fdd9 100644 --- a/util/app-config/src/args.rs +++ b/util/app-config/src/args.rs @@ -28,6 +28,7 @@ pub struct RunArgs { pub struct ProfArgs { pub config: Box, pub consensus: Consensus, + pub tmp_target: PathBuf, pub from: u64, pub to: u64, } diff --git a/util/app-config/src/cli.rs b/util/app-config/src/cli.rs index 23b2631361..128156eaf9 100644 --- a/util/app-config/src/cli.rs +++ b/util/app-config/src/cli.rs @@ -41,6 +41,7 @@ pub const ARG_NETWORK: &str = "network"; pub const ARG_NETWORK_PEER_STORE: &str = "network-peer-store"; pub const ARG_NETWORK_SECRET_KEY: &str = "network-secret-key"; pub const ARG_LOGS: &str = "logs"; +pub const ARG_TMP_TARGET: &str = "tmp-target"; const GROUP_BA: &str = "ba"; @@ -174,20 +175,23 @@ pub(crate) fn stats() -> App<'static, 'static> { fn prof() -> App<'static, 'static> { SubCommand::with_name(CMD_PROF) .about( - "Profiles ckb node\n\ + "Profiles ckb process block\n\ Example: Process 1..500 blocks then output flagme graph\n\ - cargo flamegraph --bin ckb -- -C prof 1 500", + cargo flamegraph --bin ckb -- -C prof 1 500", ) + .arg(Arg::with_name(ARG_TMP_TARGET).required(true).index(1).help( + "Specifies a target path, prof command make a temporary directory inside of target and the directory will be automatically deleted when finished", + )) .arg( Arg::with_name(ARG_FROM) .required(true) - .index(1) + .index(2) .help("Specifies from block number."), ) .arg( Arg::with_name(ARG_TO) .required(true) - .index(2) + .index(3) .help("Specifies to block number."), ) } diff --git a/util/app-config/src/lib.rs b/util/app-config/src/lib.rs index 4f277a394c..de8f48f876 100644 --- a/util/app-config/src/lib.rs +++ b/util/app-config/src/lib.rs @@ -129,12 +129,14 @@ impl Setup { pub fn prof<'m>(self, matches: &ArgMatches<'m>) -> Result { let consensus = self.consensus()?; let config = self.config.into_ckb()?; + let tmp_target = value_t!(matches, cli::ARG_TMP_TARGET, PathBuf)?; let from = value_t!(matches, cli::ARG_FROM, u64)?; let to = value_t!(matches, cli::ARG_TO, u64)?; Ok(ProfArgs { config, consensus, + tmp_target, from, to, })