mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 02:51:08 +00:00
node: exit on GRANDPA voter or BABE authoring error (#3353)
* node: exit on GRANDPA voter or BABE authoring error * node: exit process with non-zero return code when service fails * service: rename infallible task to essential task * service: revert field name changes * core: fix service testnet
This commit is contained in:
committed by
Robert Habermeier
parent
09b57261df
commit
70d716dc48
@@ -502,7 +502,7 @@ impl<Factory: ServiceFactory> DerefMut for FullComponents<Factory> {
|
||||
|
||||
impl<Factory: ServiceFactory> Future for FullComponents<Factory> {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
type Error = super::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.service.poll()
|
||||
@@ -627,7 +627,7 @@ impl<Factory: ServiceFactory> DerefMut for LightComponents<Factory> {
|
||||
|
||||
impl<Factory: ServiceFactory> Future for LightComponents<Factory> {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
type Error = super::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.service.poll()
|
||||
|
||||
@@ -28,6 +28,7 @@ pub mod error;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::{Duration, Instant};
|
||||
use futures::sync::mpsc;
|
||||
use parking_lot::Mutex;
|
||||
@@ -82,8 +83,14 @@ pub struct Service<Components: components::Components> {
|
||||
NetworkStatus<ComponentBlock<Components>>, NetworkState
|
||||
)>>>>,
|
||||
transaction_pool: Arc<TransactionPool<Components::TransactionPoolApi>>,
|
||||
/// A future that resolves when the service has exited, this is useful to
|
||||
/// make sure any internally spawned futures stop when the service does.
|
||||
exit: exit_future::Exit,
|
||||
/// A signal that makes the exit future above resolve, fired on service drop.
|
||||
signal: Option<Signal>,
|
||||
/// Set to `true` when a spawned essential task has failed. The next time
|
||||
/// the service future is polled it should complete with an error.
|
||||
essential_failed: Arc<AtomicBool>,
|
||||
/// Sender for futures that must be spawned as background tasks.
|
||||
to_spawn_tx: mpsc::UnboundedSender<Box<dyn Future<Item = (), Error = ()> + Send>>,
|
||||
/// Receiver for futures that must be spawned as background tasks.
|
||||
@@ -395,7 +402,7 @@ impl<Components: components::Components> Service<Components> {
|
||||
|
||||
// Telemetry
|
||||
let telemetry = config.telemetry_endpoints.clone().map(|endpoints| {
|
||||
let is_authority = config.roles == Roles::AUTHORITY;
|
||||
let is_authority = config.roles.is_authority();
|
||||
let network_id = network.local_peer_id().to_base58();
|
||||
let name = config.name.clone();
|
||||
let impl_name = config.impl_name.to_owned();
|
||||
@@ -440,12 +447,13 @@ impl<Components: components::Components> Service<Components> {
|
||||
network_status_sinks,
|
||||
select_chain,
|
||||
transaction_pool,
|
||||
exit,
|
||||
signal: Some(signal),
|
||||
essential_failed: Arc::new(AtomicBool::new(false)),
|
||||
to_spawn_tx,
|
||||
to_spawn_rx,
|
||||
to_poll: Vec::new(),
|
||||
config,
|
||||
exit,
|
||||
rpc_handlers,
|
||||
_rpc: rpc,
|
||||
_telemetry: telemetry,
|
||||
@@ -491,6 +499,19 @@ impl<Components: components::Components> Service<Components> {
|
||||
let _ = self.to_spawn_tx.unbounded_send(Box::new(task));
|
||||
}
|
||||
|
||||
/// Spawns a task in the background that runs the future passed as
|
||||
/// parameter. The given task is considered essential, i.e. if it errors we
|
||||
/// trigger a service exit.
|
||||
pub fn spawn_essential_task(&self, task: impl Future<Item = (), Error = ()> + Send + 'static) {
|
||||
let essential_failed = self.essential_failed.clone();
|
||||
let essential_task = Box::new(task.map_err(move |_| {
|
||||
error!("Essential task failed. Shutting down service.");
|
||||
essential_failed.store(true, Ordering::Relaxed);
|
||||
}));
|
||||
|
||||
let _ = self.to_spawn_tx.unbounded_send(essential_task);
|
||||
}
|
||||
|
||||
/// Returns a handle for spawning tasks.
|
||||
pub fn spawn_task_handle(&self) -> SpawnTaskHandle {
|
||||
SpawnTaskHandle {
|
||||
@@ -548,9 +569,13 @@ impl<Components: components::Components> Service<Components> {
|
||||
|
||||
impl<Components> Future for Service<Components> where Components: components::Components {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
type Error = Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
if self.essential_failed.load(Ordering::Relaxed) {
|
||||
return Err(Error::Other("Essential task failed.".into()));
|
||||
}
|
||||
|
||||
while let Ok(Async::Ready(Some(task_to_spawn))) = self.to_spawn_rx.poll() {
|
||||
let executor = tokio_executor::DefaultExecutor::current();
|
||||
if let Err(err) = executor.execute(task_to_spawn) {
|
||||
|
||||
Reference in New Issue
Block a user