Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

staking-miner: Add handling of SIGTERM, SIGKILL, SIGQUIT and SIGINT #5780

Merged
merged 4 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions utils/staking-miner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ edition = "2021"
[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0" }
clap = { version = "3.1", features = ["derive", "env"] }
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
jsonrpsee = { version = "0.14.0", features = ["ws-client", "macros"] }
log = "0.4.17"
paste = "1.0.7"
serde = "1.0.137"
serde_json = "1.0"
thiserror = "1.0.31"
tokio = { version = "1.18.2", features = ["macros", "rt-multi-thread", "sync"] }

remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master" }

signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
Expand All @@ -39,8 +38,11 @@ runtime-common = { package = "polkadot-runtime-common", path = "../../runtime/co
polkadot-runtime = { path = "../../runtime/polkadot" }
kusama-runtime = { path = "../../runtime/kusama" }
westend-runtime = { path = "../../runtime/westend" }
exitcode = "1.1"

sub-tokens = { git = "https://github.com/paritytech/substrate-debug-kit", branch = "master" }
signal-hook = "0.3"
futures-util = "0.3"

[dev-dependencies]
assert_cmd = "2.0.4"
51 changes: 51 additions & 0 deletions utils/staking-miner/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,18 @@ use crate::opts::*;
use clap::Parser;
use frame_election_provider_support::NposSolver;
use frame_support::traits::Get;
use futures_util::StreamExt;
use jsonrpsee::ws_client::{WsClient, WsClientBuilder};
use remote_externalities::{Builder, Mode, OnlineConfig};
use rpc::{RpcApiClient, SharedRpcClient};
use runtime_versions::RuntimeVersions;
use signal_hook::consts::signal::*;
use signal_hook_tokio::Signals;
use sp_npos_elections::BalancingConfig;
use sp_runtime::{traits::Block as BlockT, DeserializeOwned};
use std::{ops::Deref, sync::Arc};
use tracing_subscriber::{fmt, EnvFilter};

pub(crate) enum AnyRuntime {
Polkadot,
Kusama,
Expand Down Expand Up @@ -437,13 +441,57 @@ pub(crate) async fn check_versions<T: frame_system::Config + EPM::Config>(
}
}

/// Control how we exit the application
fn controlled_exit(code: i32) {
log::info!(target: LOG_TARGET, "Exiting application");
std::process::exit(code);
}

/// Handles the various signal and exit the application
/// when appropriate.
async fn handle_signals(mut signals: Signals) {
let mut keyboard_sig_count: u8 = 0;
while let Some(signal) = signals.next().await {
match signal {
// Interrupts come from the keyboard
SIGQUIT | SIGINT => {
if keyboard_sig_count >= 1 {
log::info!(
target: LOG_TARGET,
"Received keyboard termination signal #{}/{}, quitting...",
keyboard_sig_count + 1,
2
);
controlled_exit(exitcode::OK);
}
keyboard_sig_count += 1;
log::warn!(
target: LOG_TARGET,
"Received keyboard termination signal #{}, if you keep doing that I will really quit",
keyboard_sig_count
);
},

SIGKILL | SIGTERM => {
log::info!(target: LOG_TARGET, "Received SIGKILL | SIGTERM, quitting...");
controlled_exit(exitcode::OK);
},
_ => unreachable!(),
}
}
}

#[tokio::main]
async fn main() {
fmt().with_env_filter(EnvFilter::from_default_env()).init();

let Opt { uri, command } = Opt::parse();
log::debug!(target: LOG_TARGET, "attempting to connect to {:?}", uri);

let signals = Signals::new(&[SIGTERM, SIGINT, SIGQUIT]).expect("Failed initializing Signals");
let handle = signals.handle();
let signals_task = tokio::spawn(handle_signals(signals));

let rpc = loop {
match SharedRpcClient::new(&uri).await {
Ok(client) => break client,
Expand Down Expand Up @@ -555,6 +603,9 @@ async fn main() {
}
};
log::info!(target: LOG_TARGET, "round of execution finished. outcome = {:?}", outcome);

handle.close();
let _ = signals_task.await;
}

#[cfg(test)]
Expand Down