Moved syncing log out of the client (#1670)

This commit is contained in:
Arkadiy Paronyan
2016-07-20 12:36:20 +02:00
committed by Gav Wood
parent 0cba70fba3
commit b007770ba8
8 changed files with 120 additions and 103 deletions

View File

@@ -18,12 +18,15 @@ extern crate ansi_term;
use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue};
use self::ansi_term::Style;
use std::sync::{Arc};
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use std::time::{Instant, Duration};
use std::ops::{Deref, DerefMut};
use isatty::{stdout_isatty};
use ethsync::{SyncStatus, NetworkConfiguration};
use util::{Uint, RwLock};
use ethsync::{SyncProvider, ManageNetwork};
use util::{Uint, RwLock, Mutex, H256, Colour};
use ethcore::client::*;
use ethcore::views::BlockView;
use number_prefix::{binary_prefix, Standalone, Prefixed};
pub struct Informant {
@@ -32,18 +35,11 @@ pub struct Informant {
report: RwLock<Option<ClientReport>>,
last_tick: RwLock<Instant>,
with_color: bool,
}
impl Default for Informant {
fn default() -> Self {
Informant {
chain_info: RwLock::new(None),
cache_info: RwLock::new(None),
report: RwLock::new(None),
last_tick: RwLock::new(Instant::now()),
with_color: true,
}
}
client: Arc<Client>,
sync: Option<Arc<SyncProvider>>,
net: Option<Arc<ManageNetwork>>,
last_import: Mutex<Instant>,
skipped: AtomicUsize,
}
trait MillisecondDuration {
@@ -58,13 +54,18 @@ impl MillisecondDuration for Duration {
impl Informant {
/// Make a new instance potentially `with_color` output.
pub fn new(with_color: bool) -> Self {
pub fn new(client: Arc<Client>, sync: Option<Arc<SyncProvider>>, net: Option<Arc<ManageNetwork>>, with_color: bool) -> Self {
Informant {
chain_info: RwLock::new(None),
cache_info: RwLock::new(None),
report: RwLock::new(None),
last_tick: RwLock::new(Instant::now()),
with_color: with_color,
client: client,
sync: sync,
net: net,
last_import: Mutex::new(Instant::now()),
skipped: AtomicUsize::new(0),
}
}
@@ -77,17 +78,20 @@ impl Informant {
#[cfg_attr(feature="dev", allow(match_bool))]
pub fn tick(&self, client: &Client, maybe_status: Option<(SyncStatus, NetworkConfiguration)>) {
pub fn tick(&self) {
let elapsed = self.last_tick.read().elapsed();
if elapsed < Duration::from_secs(5) {
return;
}
let chain_info = client.chain_info();
let queue_info = client.queue_info();
let cache_info = client.blockchain_cache_info();
let chain_info = self.client.chain_info();
let queue_info = self.client.queue_info();
let cache_info = self.client.blockchain_cache_info();
let network_config = self.net.as_ref().map(|n| n.network_config());
let sync_status = self.sync.as_ref().map(|s| s.status());
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3;
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3
|| self.sync.as_ref().map_or(false, |s| s.status().is_major_syncing());
if !importing && elapsed < Duration::from_secs(30) {
return;
}
@@ -95,7 +99,7 @@ impl Informant {
*self.last_tick.write() = Instant::now();
let mut write_report = self.report.write();
let report = client.report();
let report = self.client.report();
let paint = |c: Style, t: String| match self.with_color && stdout_isatty() {
true => format!("{}", c.paint(t)),
@@ -120,8 +124,8 @@ impl Informant {
),
false => String::new(),
},
match maybe_status {
Some((ref sync_info, ref net_config)) => format!("{}{}/{}/{} peers",
match (&sync_status, &network_config) {
(&Some(ref sync_info), &Some(ref net_config)) => format!("{}{}/{}/{} peers",
match importing {
true => format!("{} ", paint(Green.bold(), format!("{:>8}", format!("#{}", sync_info.last_imported_block_number.unwrap_or(chain_info.best_block_number))))),
false => String::new(),
@@ -130,14 +134,14 @@ impl Informant {
paint(Cyan.bold(), format!("{:2}", sync_info.num_peers)),
paint(Cyan.bold(), format!("{:2}", net_config.ideal_peers))
),
None => String::new(),
_ => String::new(),
},
format!("{} db {} chain {} queue{}",
format!("{} db {} chain {} queue{}",
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(report.state_db_mem))),
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(cache_info.total()))),
paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(queue_info.mem_used))),
match maybe_status {
Some((ref sync_info, _)) => format!(" {} sync", paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used)))),
match sync_status {
Some(ref sync_info) => format!(" {} sync", paint(Blue.bold(), format!("{:>8}", Informant::format_bytes(sync_info.mem_used)))),
_ => String::new(),
}
)
@@ -149,3 +153,36 @@ impl Informant {
}
}
impl ChainNotify for Informant {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, duration: u64) {
let mut last_import = self.last_import.lock();
if Instant::now() > *last_import + Duration::from_secs(1) {
let queue_info = self.client.queue_info();
let importing = queue_info.unverified_queue_size + queue_info.verified_queue_size > 3
|| self.sync.as_ref().map_or(false, |s| s.status().is_major_syncing());
if !importing {
if let Some(block) = enacted.last().and_then(|h| self.client.block(BlockID::Hash(h.clone()))) {
let view = BlockView::new(&block);
let header = view.header();
let tx_count = view.transactions_count();
let size = block.len();
let skipped = self.skipped.load(AtomicOrdering::Relaxed);
info!(target: "import", "Imported {} {} ({} txs, {} Mgas, {} ms, {} KiB){}",
Colour::White.bold().paint(format!("#{}", header.number())),
Colour::White.bold().paint(format!("{}", header.hash())),
Colour::Yellow.bold().paint(format!("{}", tx_count)),
Colour::Yellow.bold().paint(format!("{:.2}", header.gas_used.low_u64() as f32 / 1000000f32)),
Colour::Purple.bold().paint(format!("{:.2}", duration as f32 / 1000000f32)),
Colour::Blue.bold().paint(format!("{:.2}", size as f32 / 1024f32)),
if skipped > 0 { format!(" + another {} block(s)", Colour::Red.bold().paint(format!("{}", skipped))) } else { String::new() }
);
*last_import = Instant::now();
}
}
self.skipped.store(0, AtomicOrdering::Relaxed);
} else {
self.skipped.fetch_add(enacted.len(), AtomicOrdering::Relaxed);
}
}
}

View File

@@ -30,7 +30,7 @@ pub struct ClientIoHandler {
pub sync: Arc<SyncProvider>,
pub net: Arc<ManageNetwork>,
pub accounts: Arc<AccountProvider>,
pub info: Informant,
pub info: Arc<Informant>,
}
impl IoHandler<ClientIoMessage> for ClientIoHandler {
@@ -40,9 +40,7 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
if let INFO_TIMER = timer {
let sync_status = self.sync.status();
let network_config = self.net.network_config();
self.info.tick(&self.client, Some((sync_status, network_config)));
self.info.tick();
}
}
}

View File

@@ -86,7 +86,7 @@ use rustc_serialize::hex::FromHex;
use ctrlc::CtrlC;
use util::{H256, ToPretty, PayloadInfo, Bytes, Colour, version, journaldb, RotatingLogger};
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, Mode};
use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError, Mode, ChainNotify};
use ethcore::error::{ImportError};
use ethcore::service::ClientService;
use ethcore::spec::Spec;
@@ -246,7 +246,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig,
let (sync_provider, manage_network, chain_notify) =
modules::sync(sync_config, NetworkConfiguration::from(net_settings), client.clone())
.unwrap_or_else(|e| die_with_error("Sync", e));
service.set_notify(&chain_notify);
service.add_notify(&chain_notify);
// if network is active by default
if match conf.mode() { Mode::Dark(..) => false, _ => !conf.args.flag_no_network } {
@@ -310,10 +310,13 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig,
apis: deps_for_rpc_apis.clone(),
});
let informant = Arc::new(Informant::new(service.client(), Some(sync_provider.clone()), Some(manage_network.clone()), conf.have_color()));
let info_notify: Arc<ChainNotify> = informant.clone();
service.add_notify(&info_notify);
// Register IO handler
let io_handler = Arc::new(ClientIoHandler {
client: service.client(),
info: Informant::new(conf.have_color()),
info: informant,
sync: sync_provider.clone(),
net: manage_network.clone(),
accounts: account_service.clone(),
@@ -439,7 +442,7 @@ fn execute_import(conf: Configuration, panic_handler: Arc<PanicHandler>) {
}
};
let informant = Informant::new(conf.have_color());
let informant = Informant::new(client.clone(), None, None, conf.have_color());
let do_import = |bytes| {
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
@@ -448,7 +451,7 @@ fn execute_import(conf: Configuration, panic_handler: Arc<PanicHandler>) {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { trace!("Skipping block already in chain."); }
Err(e) => die!("Cannot import block: {:?}", e)
}
informant.tick(&*client, None);
informant.tick();
};
match format {
@@ -476,7 +479,7 @@ fn execute_import(conf: Configuration, panic_handler: Arc<PanicHandler>) {
}
while !client.queue_info().is_empty() {
sleep(Duration::from_secs(1));
informant.tick(&*client, None);
informant.tick();
}
client.flush_queue();
}