Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
14 changes: 4 additions & 10 deletions polkadot/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not sure how it works. The second item in tuple of Action::RunService is bound to be IntoExit, why it's called worker here? Why worker.configuration() works here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action returns back the same thing that was passed to prepare_execution if it was not used.

info!("Parity ·:· Polkadot");
info!(" version {}", config.full_version());
info!(" by Parity Technologies, 2017, 2018");
Expand Down
19 changes: 12 additions & 7 deletions polkadot/collator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down
14 changes: 8 additions & 6 deletions polkadot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

// can't use signal directly here because CtrlC takes only `Fn`.
let (exit_send, exit) = oneshot::channel();

Expand All @@ -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()
}
}

Expand Down
22 changes: 15 additions & 7 deletions substrate/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>,
{
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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<()>
Expand Down