use crate::{chain, client::Client, prelude::*};
use abscissa_core::Command;
use clap::Parser;
use std::{path::PathBuf, process};
#[derive(Command, Debug, Default, Parser)]
pub struct StartCommand {
#[clap(short = 'c', long = "config")]
pub config: Option<PathBuf>,
#[clap(short = 'v', long = "verbose")]
pub verbose: bool,
}
impl Runnable for StartCommand {
fn run(&self) {
info!(
"{} {} starting up...",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
);
run_app(self.spawn_clients());
}
}
impl StartCommand {
fn spawn_clients(&self) -> Vec<Client> {
let config = APP.config();
chain::load_config(&config).unwrap_or_else(|e| {
status_err!("error loading configuration: {}", e);
process::exit(1);
});
config
.validator
.iter()
.cloned()
.map(Client::spawn)
.collect()
}
}
fn run_app(validator_clients: Vec<Client>) {
blocking_wait(validator_clients);
}
fn blocking_wait(validator_clients: Vec<Client>) {
debug!("Main thread waiting on clients...");
let mut success = true;
for client in validator_clients {
let name = client.name().to_owned();
if let Err(e) = client.join() {
status_err!("client '{}' exited with error: {}", name, e);
success = false;
}
}
if success {
info!("Shutdown completed successfully");
} else {
warn!("Shutdown completed with errors");
process::exit(1);
}
}