From 31db321814810a484c6ad3be0e4795ec4e83d586 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan <arkady.paronyan@gmail.com> Date: Sat, 28 Jul 2018 08:31:16 +0200 Subject: [PATCH] Exit signal gets its own trait (#433) * Exit signal gets its own trait * Typo * Removed clone bounds --- substrate/polkadot/cli/src/lib.rs | 14 ++++---------- substrate/polkadot/collator/src/lib.rs | 19 ++++++++++++------- substrate/polkadot/src/main.rs | 14 ++++++++------ substrate/substrate/cli/src/lib.rs | 22 +++++++++++++++------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/substrate/polkadot/cli/src/lib.rs b/substrate/polkadot/cli/src/lib.rs index ba29a39ecce..b2da24ee103 100644 --- a/substrate/polkadot/cli/src/lib.rs +++ b/substrate/polkadot/cli/src/lib.rs @@ -38,7 +38,7 @@ use chain_spec::ChainSpec; use futures::Future; use tokio::runtime::Runtime; pub use service::{Components as ServiceComponents, Service, CustomConfiguration}; -pub use cli::VersionInfo; +pub use cli::{VersionInfo, IntoExit}; fn load_spec(id: &str) -> Result<Option<service::ChainSpec>, String> { Ok(match ChainSpec::from(id) { @@ -51,22 +51,16 @@ fn load_spec(id: &str) -> Result<Option<service::ChainSpec>, String> { /// /// This will be invoked with the service and spawn a future that resolves /// when complete. -pub trait Worker { +pub trait Worker: IntoExit { /// A future that resolves when the work is done or the node should exit. /// This will be run on a tokio runtime. type Work: Future<Item=(),Error=()> + Send + 'static; - /// An exit scheduled for the future. - type Exit: Future<Item=(),Error=()> + Send + 'static; - /// Return configuration for the polkadot node. // TODO: make this the full configuration, so embedded nodes don't need // string CLI args fn configuration(&self) -> service::CustomConfiguration { Default::default() } - /// Don't work, but schedule an exit. - fn exit_only(&self) -> Self::Exit; - /// Do work and schedule exit. fn work<C: service::Components>(self, service: &service::Service<C>) -> Self::Work; } @@ -85,9 +79,9 @@ pub fn run<I, T, W>(args: I, worker: W, version: cli::VersionInfo) -> error::Res W: Worker, { - match cli::prepare_execution::<service::Factory, _, _, _, _>(args, worker.exit_only(), version, load_spec, "parity-polkadot")? { + match cli::prepare_execution::<service::Factory, _, _, _, _>(args, worker, version, load_spec, "parity-polkadot")? { cli::Action::ExecutedInternally => (), - cli::Action::RunService(mut config) => { + cli::Action::RunService((mut config, worker)) => { info!("Parity ·:· Polkadot"); info!(" version {}", config.full_version()); info!(" by Parity Technologies, 2017, 2018"); diff --git a/substrate/polkadot/collator/src/lib.rs b/substrate/polkadot/collator/src/lib.rs index 0acee408b68..37428495d9d 100644 --- a/substrate/polkadot/collator/src/lib.rs +++ b/substrate/polkadot/collator/src/lib.rs @@ -69,7 +69,7 @@ use polkadot_api::PolkadotApi; use polkadot_primitives::{AccountId, BlockId, SessionKey}; use polkadot_primitives::parachain::{self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId}; use polkadot_cli::{ServiceComponents, Service, CustomConfiguration, VersionInfo}; -use polkadot_cli::Worker; +use polkadot_cli::{Worker, IntoExit}; use tokio::timer::Deadline; const COLLATION_TIMEOUT: Duration = Duration::from_secs(30); @@ -211,12 +211,21 @@ struct CollationNode<P, E> { key: Arc<ed25519::Pair>, } +impl<P, E> IntoExit for CollationNode<P, E> where + P: ParachainContext + Send + 'static, + E: Future<Item=(),Error=()> + Send + 'static +{ + type Exit = E; + fn into_exit(self) -> Self::Exit { + self.exit + } +} + impl<P, E> Worker for CollationNode<P, E> where P: ParachainContext + Send + 'static, - E: Future<Item=(),Error=()> + Send + Clone + 'static + E: Future<Item=(),Error=()> + Send + 'static { type Work = Box<Future<Item=(),Error=()> + Send>; - type Exit = E; fn configuration(&self) -> CustomConfiguration { let mut config = CustomConfiguration::default(); @@ -227,10 +236,6 @@ impl<P, E> Worker for CollationNode<P, E> where config } - fn exit_only(&self) -> Self::Exit { - self.exit.clone() - } - fn work<C: ServiceComponents>(self, service: &Service<C>) -> Self::Work { let CollationNode { parachain_context, exit, para_id, key } = self; let client = service.client(); diff --git a/substrate/polkadot/src/main.rs b/substrate/polkadot/src/main.rs index 4e3fba054f9..d3e951596e2 100644 --- a/substrate/polkadot/src/main.rs +++ b/substrate/polkadot/src/main.rs @@ -38,11 +38,9 @@ mod vergen { // the regular polkadot worker simply does nothing until ctrl-c struct Worker; -impl cli::Worker for Worker { - type Work = Self::Exit; +impl cli::IntoExit for Worker { type Exit = future::MapErr<oneshot::Receiver<()>, fn(oneshot::Canceled) -> ()>; - - fn exit_only(&self) -> Self::Exit { + fn into_exit(self) -> Self::Exit { // can't use signal directly here because CtrlC takes only `Fn`. let (exit_send, exit) = oneshot::channel(); @@ -55,9 +53,13 @@ impl cli::Worker for Worker { exit.map_err(drop) } +} - fn work<C: ServiceComponents>(self, _service: &Service<C>) -> Self::Exit { - self.exit_only() +impl cli::Worker for Worker { + type Work = <Self as cli::IntoExit>::Exit; + fn work<C: ServiceComponents>(self, _service: &Service<C>) -> Self::Work { + use cli::IntoExit; + self.into_exit() } } diff --git a/substrate/substrate/cli/src/lib.rs b/substrate/substrate/cli/src/lib.rs index 4feeb711f37..324121073ea 100644 --- a/substrate/substrate/cli/src/lib.rs +++ b/substrate/substrate/cli/src/lib.rs @@ -85,11 +85,19 @@ pub struct VersionInfo { } /// CLI Action -pub enum Action<F: ServiceFactory> { +pub enum Action<F: ServiceFactory, E: IntoExit> { /// Substrate handled the command. No need to do anything. ExecutedInternally, /// Service mode requested. Caller should start the service. - RunService(FactoryFullConfiguration<F>), + RunService((FactoryFullConfiguration<F>, E)), +} + +/// Something that can be converted into an exit signal. +pub trait IntoExit { + /// Exit signal type. + type Exit: Future<Item=(),Error=()> + Send + 'static; + /// Convert into exit signal. + fn into_exit(self) -> Self::Exit; } fn load_spec<F, G>(matches: &clap::ArgMatches, factory: F) -> Result<ChainSpec<G>, String> @@ -146,11 +154,11 @@ pub fn prepare_execution<F, I, T, E, S>( version: VersionInfo, spec_factory: S, impl_name: &'static str, -) -> error::Result<Action<F>> +) -> error::Result<Action<F, E>> where I: IntoIterator<Item = T>, T: Into<std::ffi::OsString> + Clone, - E: Future<Item=(),Error=()> + Send + 'static, + E: IntoExit, F: ServiceFactory, S: FnOnce(&str) -> Result<Option<ChainSpec<FactoryGenesis<F>>>, String>, { @@ -182,13 +190,13 @@ where if let Some(matches) = matches.subcommand_matches("export-blocks") { let spec = load_spec(&matches, spec_factory)?; - export_blocks::<F, _>(matches, spec, exit)?; + export_blocks::<F, _>(matches, spec, exit.into_exit())?; return Ok(Action::ExecutedInternally); } if let Some(matches) = matches.subcommand_matches("import-blocks") { let spec = load_spec(&matches, spec_factory)?; - import_blocks::<F, _>(matches, spec, exit)?; + import_blocks::<F, _>(matches, spec, exit.into_exit())?; return Ok(Action::ExecutedInternally); } @@ -298,7 +306,7 @@ where config.telemetry_url = Some(url.to_owned()); } - Ok(Action::RunService(config)) + Ok(Action::RunService((config, exit))) } fn build_spec<F>(matches: &clap::ArgMatches, spec: ChainSpec<FactoryGenesis<F>>) -> error::Result<()> -- GitLab