Try flushing streams before exiting Zebra (#2911)
This commit is contained in:
parent
92634f788b
commit
e277975d85
|
|
@ -5,7 +5,14 @@ mod disk_format;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use std::{borrow::Borrow, collections::HashMap, convert::TryInto, path::Path, sync::Arc};
|
use std::{
|
||||||
|
borrow::Borrow,
|
||||||
|
collections::HashMap,
|
||||||
|
convert::TryInto,
|
||||||
|
io::{stderr, stdout, Write},
|
||||||
|
path::Path,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use zebra_chain::{
|
use zebra_chain::{
|
||||||
amount::NonNegative,
|
amount::NonNegative,
|
||||||
|
|
@ -126,8 +133,8 @@ impl FinalizedState {
|
||||||
// So we want to drop it before we exit.
|
// So we want to drop it before we exit.
|
||||||
tracing::info!("closing cached state");
|
tracing::info!("closing cached state");
|
||||||
std::mem::drop(new_state);
|
std::mem::drop(new_state);
|
||||||
tracing::info!("exiting Zebra");
|
|
||||||
std::process::exit(0);
|
Self::exit_process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,20 +474,36 @@ impl FinalizedState {
|
||||||
|
|
||||||
// We'd like to drop the database here, because that closes the
|
// We'd like to drop the database here, because that closes the
|
||||||
// column families and the database. But Rust's ownership rules
|
// column families and the database. But Rust's ownership rules
|
||||||
// make that difficult, so we just flush instead.
|
// make that difficult, so we just flush and delete ephemeral data instead.
|
||||||
|
|
||||||
// TODO: remove these extra logs once bugs like #2905 are fixed
|
// TODO: remove these extra logs once bugs like #2905 are fixed
|
||||||
self.db.flush().expect("flush is successful");
|
self.db.flush().expect("flush is successful");
|
||||||
tracing::info!("flushed database to disk");
|
tracing::info!("flushed database to disk");
|
||||||
|
|
||||||
self.delete_ephemeral();
|
self.delete_ephemeral();
|
||||||
tracing::info!("exiting Zebra");
|
|
||||||
std::process::exit(0);
|
Self::exit_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
result.map_err(Into::into)
|
result.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Exit the host process.
|
||||||
|
///
|
||||||
|
/// Designed for debugging and tests.
|
||||||
|
fn exit_process() -> ! {
|
||||||
|
tracing::info!("exiting Zebra");
|
||||||
|
|
||||||
|
// Some OSes require a flush to send all output to the terminal.
|
||||||
|
// Zebra's logging doesn't depend on `tokio`, so we flush the stdlib sync streams.
|
||||||
|
//
|
||||||
|
// TODO: if this doesn't work, send an empty line as well.
|
||||||
|
let _ = stdout().lock().flush();
|
||||||
|
let _ = stderr().lock().flush();
|
||||||
|
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
/// Commit a finalized block to the state.
|
/// Commit a finalized block to the state.
|
||||||
///
|
///
|
||||||
/// It's the caller's responsibility to ensure that blocks are committed in
|
/// It's the caller's responsibility to ensure that blocks are committed in
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,19 @@
|
||||||
//! Zebrad Abscissa Application
|
//! Zebrad Abscissa Application
|
||||||
|
|
||||||
use crate::{commands::ZebradCmd, components::tracing::Tracing, config::ZebradConfig};
|
use std::{io::Write, process};
|
||||||
|
|
||||||
use abscissa_core::{
|
use abscissa_core::{
|
||||||
application::{self, AppCell},
|
application::{self, fatal_error, AppCell},
|
||||||
config,
|
config::{self, Configurable},
|
||||||
config::Configurable,
|
terminal::{component::Terminal, stderr, stdout, ColorChoice},
|
||||||
terminal::component::Terminal,
|
|
||||||
terminal::ColorChoice,
|
|
||||||
Application, Component, EntryPoint, FrameworkError, Shutdown, StandardPaths, Version,
|
Application, Component, EntryPoint, FrameworkError, Shutdown, StandardPaths, Version,
|
||||||
};
|
};
|
||||||
use application::fatal_error;
|
|
||||||
use std::process;
|
|
||||||
|
|
||||||
use zebra_network::constants::PORT_IN_USE_ERROR;
|
use zebra_network::constants::PORT_IN_USE_ERROR;
|
||||||
use zebra_state::constants::{DATABASE_FORMAT_VERSION, LOCK_FILE_ERROR};
|
use zebra_state::constants::{DATABASE_FORMAT_VERSION, LOCK_FILE_ERROR};
|
||||||
|
|
||||||
|
use crate::{commands::ZebradCmd, components::tracing::Tracing, config::ZebradConfig};
|
||||||
|
|
||||||
/// Application state
|
/// Application state
|
||||||
pub static APPLICATION: AppCell<ZebradApp> = AppCell::new();
|
pub static APPLICATION: AppCell<ZebradApp> = AppCell::new();
|
||||||
|
|
||||||
|
|
@ -411,6 +410,15 @@ impl Application for ZebradApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(&mut self, shutdown: Shutdown) -> ! {
|
fn shutdown(&mut self, shutdown: Shutdown) -> ! {
|
||||||
|
// Some OSes require a flush to send all output to the terminal.
|
||||||
|
// zebrad's logging uses Abscissa, so we flush its streams.
|
||||||
|
//
|
||||||
|
// TODO:
|
||||||
|
// - if this doesn't work, send an empty line as well
|
||||||
|
// - move this code to the tracing component's `before_shutdown()`
|
||||||
|
let _ = stdout().lock().flush();
|
||||||
|
let _ = stderr().lock().flush();
|
||||||
|
|
||||||
if let Err(e) = self.state().components.shutdown(self, shutdown) {
|
if let Err(e) = self.state().components.shutdown(self, shutdown) {
|
||||||
fatal_error(self, &e)
|
fatal_error(self, &e)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue