mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-24 21:45:41 +00:00
Move spawning tasks from thread pools to Service's TaskManager for block importing (#5647)
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
Generated
-1
@@ -7336,7 +7336,6 @@ version = "0.8.0-dev"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"futures 0.3.4",
|
"futures 0.3.4",
|
||||||
"futures-diagnose",
|
|
||||||
"futures-timer 3.0.2",
|
"futures-timer 3.0.2",
|
||||||
"libp2p",
|
"libp2p",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ macro_rules! new_full_start {
|
|||||||
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
||||||
Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry))
|
Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry))
|
||||||
})?
|
})?
|
||||||
.with_import_queue(|_config, client, mut select_chain, _transaction_pool| {
|
.with_import_queue(|_config, client, mut select_chain, _transaction_pool, spawn_task_handle| {
|
||||||
let select_chain = select_chain.take()
|
let select_chain = select_chain.take()
|
||||||
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
|
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
|
||||||
|
|
||||||
@@ -52,13 +52,16 @@ macro_rules! new_full_start {
|
|||||||
grandpa_block_import.clone(), client.clone(),
|
grandpa_block_import.clone(), client.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(
|
let spawner = |future| spawn_task_handle.spawn_blocking("import-queue-worker", future);
|
||||||
|
|
||||||
|
let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>(
|
||||||
sc_consensus_aura::slot_duration(&*client)?,
|
sc_consensus_aura::slot_duration(&*client)?,
|
||||||
aura_block_import,
|
aura_block_import,
|
||||||
Some(Box::new(grandpa_block_import.clone())),
|
Some(Box::new(grandpa_block_import.clone())),
|
||||||
None,
|
None,
|
||||||
client,
|
client,
|
||||||
inherent_data_providers.clone(),
|
inherent_data_providers.clone(),
|
||||||
|
spawner,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
import_setup = Some((grandpa_block_import, grandpa_link));
|
import_setup = Some((grandpa_block_import, grandpa_link));
|
||||||
@@ -191,7 +194,7 @@ pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceE
|
|||||||
);
|
);
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
})?
|
})?
|
||||||
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {
|
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool, spawn_task_handle| {
|
||||||
let fetch_checker = fetcher
|
let fetch_checker = fetcher
|
||||||
.map(|fetcher| fetcher.checker().clone())
|
.map(|fetcher| fetcher.checker().clone())
|
||||||
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
||||||
@@ -205,13 +208,16 @@ pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceE
|
|||||||
let finality_proof_request_builder =
|
let finality_proof_request_builder =
|
||||||
finality_proof_import.create_finality_proof_request_builder();
|
finality_proof_import.create_finality_proof_request_builder();
|
||||||
|
|
||||||
let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(
|
let spawner = |future| spawn_task_handle.spawn_blocking("import-queue-worker", future);
|
||||||
|
|
||||||
|
let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>(
|
||||||
sc_consensus_aura::slot_duration(&*client)?,
|
sc_consensus_aura::slot_duration(&*client)?,
|
||||||
grandpa_block_import,
|
grandpa_block_import,
|
||||||
None,
|
None,
|
||||||
Some(Box::new(finality_proof_import)),
|
Some(Box::new(finality_proof_import)),
|
||||||
client,
|
client,
|
||||||
inherent_data_providers.clone(),
|
inherent_data_providers.clone(),
|
||||||
|
spawner,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok((import_queue, finality_proof_request_builder))
|
Ok((import_queue, finality_proof_request_builder))
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ macro_rules! new_full_start {
|
|||||||
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());
|
||||||
Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry))
|
Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry))
|
||||||
})?
|
})?
|
||||||
.with_import_queue(|_config, client, mut select_chain, _transaction_pool| {
|
.with_import_queue(|_config, client, mut select_chain, _transaction_pool, spawn_task_handle| {
|
||||||
let select_chain = select_chain.take()
|
let select_chain = select_chain.take()
|
||||||
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
|
.ok_or_else(|| sc_service::Error::SelectChainRequired)?;
|
||||||
let (grandpa_block_import, grandpa_link) = grandpa::block_import(
|
let (grandpa_block_import, grandpa_link) = grandpa::block_import(
|
||||||
@@ -68,6 +68,8 @@ macro_rules! new_full_start {
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let spawner = |future| spawn_task_handle.spawn_blocking("import-queue-worker", future);
|
||||||
|
|
||||||
let import_queue = sc_consensus_babe::import_queue(
|
let import_queue = sc_consensus_babe::import_queue(
|
||||||
babe_link.clone(),
|
babe_link.clone(),
|
||||||
block_import.clone(),
|
block_import.clone(),
|
||||||
@@ -75,6 +77,7 @@ macro_rules! new_full_start {
|
|||||||
None,
|
None,
|
||||||
client,
|
client,
|
||||||
inherent_data_providers.clone(),
|
inherent_data_providers.clone(),
|
||||||
|
spawner,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
import_setup = Some((block_import, grandpa_link, babe_link));
|
import_setup = Some((block_import, grandpa_link, babe_link));
|
||||||
@@ -284,7 +287,7 @@ pub fn new_light(config: Configuration)
|
|||||||
);
|
);
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
})?
|
})?
|
||||||
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {
|
.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool, spawn_task_handle| {
|
||||||
let fetch_checker = fetcher
|
let fetch_checker = fetcher
|
||||||
.map(|fetcher| fetcher.checker().clone())
|
.map(|fetcher| fetcher.checker().clone())
|
||||||
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
||||||
@@ -305,6 +308,8 @@ pub fn new_light(config: Configuration)
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let spawner = |future| spawn_task_handle.spawn_blocking("import-queue-worker", future);
|
||||||
|
|
||||||
let import_queue = sc_consensus_babe::import_queue(
|
let import_queue = sc_consensus_babe::import_queue(
|
||||||
babe_link,
|
babe_link,
|
||||||
babe_block_import,
|
babe_block_import,
|
||||||
@@ -312,6 +317,7 @@ pub fn new_light(config: Configuration)
|
|||||||
Some(Box::new(finality_proof_import)),
|
Some(Box::new(finality_proof_import)),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
inherent_data_providers.clone(),
|
inherent_data_providers.clone(),
|
||||||
|
spawner,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok((import_queue, finality_proof_request_builder))
|
Ok((import_queue, finality_proof_request_builder))
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use names::{Generator, Name};
|
|||||||
use sc_service::config::{
|
use sc_service::config::{
|
||||||
WasmExecutionMethod, Role, OffchainWorkerConfig,
|
WasmExecutionMethod, Role, OffchainWorkerConfig,
|
||||||
Configuration, DatabaseConfig, ExtTransport, KeystoreConfig, NetworkConfiguration,
|
Configuration, DatabaseConfig, ExtTransport, KeystoreConfig, NetworkConfiguration,
|
||||||
NodeKeyConfig, PrometheusConfig, PruningMode, TelemetryEndpoints, TransactionPoolOptions,
|
NodeKeyConfig, PrometheusConfig, PruningMode, TelemetryEndpoints, TransactionPoolOptions, TaskType
|
||||||
};
|
};
|
||||||
use sc_client_api::execution_extensions::ExecutionStrategies;
|
use sc_client_api::execution_extensions::ExecutionStrategies;
|
||||||
use sc_service::{ChainSpec, TracingReceiver};
|
use sc_service::{ChainSpec, TracingReceiver};
|
||||||
@@ -385,7 +385,7 @@ pub trait CliConfiguration: Sized {
|
|||||||
fn create_configuration<C: SubstrateCli>(
|
fn create_configuration<C: SubstrateCli>(
|
||||||
&self,
|
&self,
|
||||||
cli: &C,
|
cli: &C,
|
||||||
task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + Sync>,
|
task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>, TaskType) + Send + Sync>,
|
||||||
) -> Result<Configuration> {
|
) -> Result<Configuration> {
|
||||||
let is_dev = self.is_dev()?;
|
let is_dev = self.is_dev()?;
|
||||||
let chain_id = self.chain_id(is_dev)?;
|
let chain_id = self.chain_id(is_dev)?;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ use log::info;
|
|||||||
pub use params::*;
|
pub use params::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
pub use runner::*;
|
pub use runner::*;
|
||||||
use sc_service::{ChainSpec, Configuration};
|
use sc_service::{ChainSpec, Configuration, TaskType};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@@ -177,7 +177,7 @@ pub trait SubstrateCli: Sized {
|
|||||||
fn create_configuration<T: CliConfiguration>(
|
fn create_configuration<T: CliConfiguration>(
|
||||||
&self,
|
&self,
|
||||||
command: &T,
|
command: &T,
|
||||||
task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + Sync>,
|
task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>, TaskType) + Send + Sync>,
|
||||||
) -> error::Result<Configuration> {
|
) -> error::Result<Configuration> {
|
||||||
command.create_configuration(self, task_executor)
|
command.create_configuration(self, task_executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use futures::pin_mut;
|
|||||||
use futures::select;
|
use futures::select;
|
||||||
use futures::{future, future::FutureExt, Future};
|
use futures::{future, future::FutureExt, Future};
|
||||||
use log::info;
|
use log::info;
|
||||||
use sc_service::{AbstractService, Configuration, Role, ServiceBuilderCommand};
|
use sc_service::{AbstractService, Configuration, Role, ServiceBuilderCommand, TaskType};
|
||||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
|
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
|
||||||
use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL};
|
use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@@ -116,13 +116,22 @@ impl<C: SubstrateCli> Runner<C> {
|
|||||||
/// Create a new runtime with the command provided in argument
|
/// Create a new runtime with the command provided in argument
|
||||||
pub fn new<T: CliConfiguration>(cli: &C, command: &T) -> Result<Runner<C>> {
|
pub fn new<T: CliConfiguration>(cli: &C, command: &T) -> Result<Runner<C>> {
|
||||||
let tokio_runtime = build_runtime()?;
|
let tokio_runtime = build_runtime()?;
|
||||||
|
let runtime_handle = tokio_runtime.handle().clone();
|
||||||
|
|
||||||
let task_executor = {
|
let task_executor = Arc::new(
|
||||||
let runtime_handle = tokio_runtime.handle().clone();
|
move |fut, task_type| {
|
||||||
Arc::new(move |fut| {
|
match task_type {
|
||||||
runtime_handle.spawn(fut);
|
TaskType::Async => { runtime_handle.spawn(fut); }
|
||||||
})
|
TaskType::Blocking => {
|
||||||
};
|
runtime_handle.spawn( async move {
|
||||||
|
// `spawn_blocking` is looking for the current runtime, and as such has to be called
|
||||||
|
// from within `spawn`.
|
||||||
|
tokio::task::spawn_blocking(move || futures::executor::block_on(fut))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Runner {
|
Ok(Runner {
|
||||||
config: command.create_configuration(cli, task_executor)?,
|
config: command.create_configuration(cli, task_executor)?,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ use std::{
|
|||||||
collections::HashMap
|
collections::HashMap
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures::prelude::*;
|
use futures::{prelude::*, future::BoxFuture};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use log::{debug, info, trace};
|
use log::{debug, info, trace};
|
||||||
|
|
||||||
@@ -788,13 +788,14 @@ impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Start an import queue for the Aura consensus algorithm.
|
/// Start an import queue for the Aura consensus algorithm.
|
||||||
pub fn import_queue<B, I, C, P>(
|
pub fn import_queue<B, I, C, P, F>(
|
||||||
slot_duration: SlotDuration,
|
slot_duration: SlotDuration,
|
||||||
block_import: I,
|
block_import: I,
|
||||||
justification_import: Option<BoxJustificationImport<B>>,
|
justification_import: Option<BoxJustificationImport<B>>,
|
||||||
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
||||||
client: Arc<C>,
|
client: Arc<C>,
|
||||||
inherent_data_providers: InherentDataProviders,
|
inherent_data_providers: InherentDataProviders,
|
||||||
|
spawner: F,
|
||||||
) -> Result<AuraImportQueue<B, sp_api::TransactionFor<C, B>>, sp_consensus::Error> where
|
) -> Result<AuraImportQueue<B, sp_api::TransactionFor<C, B>>, sp_consensus::Error> where
|
||||||
B: BlockT,
|
B: BlockT,
|
||||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
||||||
@@ -804,6 +805,7 @@ pub fn import_queue<B, I, C, P>(
|
|||||||
P: Pair + Send + Sync + 'static,
|
P: Pair + Send + Sync + 'static,
|
||||||
P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode,
|
P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode,
|
||||||
P::Signature: Encode + Decode,
|
P::Signature: Encode + Decode,
|
||||||
|
F: Fn(BoxFuture<'static, ()>) -> (),
|
||||||
{
|
{
|
||||||
register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?;
|
register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?;
|
||||||
initialize_authorities_cache(&*client)?;
|
initialize_authorities_cache(&*client)?;
|
||||||
@@ -818,6 +820,7 @@ pub fn import_queue<B, I, C, P>(
|
|||||||
Box::new(block_import),
|
Box::new(block_import),
|
||||||
justification_import,
|
justification_import,
|
||||||
finality_proof_import,
|
finality_proof_import,
|
||||||
|
spawner,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ use sc_client_api::{
|
|||||||
};
|
};
|
||||||
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||||
|
|
||||||
use futures::prelude::*;
|
use futures::{prelude::*, future::BoxFuture};
|
||||||
use log::{debug, info, log, trace, warn};
|
use log::{debug, info, log, trace, warn};
|
||||||
use sc_consensus_slots::{
|
use sc_consensus_slots::{
|
||||||
SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
|
SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
|
||||||
@@ -1272,6 +1272,7 @@ pub fn import_queue<Block: BlockT, Client, Inner>(
|
|||||||
finality_proof_import: Option<BoxFinalityProofImport<Block>>,
|
finality_proof_import: Option<BoxFinalityProofImport<Block>>,
|
||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
inherent_data_providers: InherentDataProviders,
|
inherent_data_providers: InherentDataProviders,
|
||||||
|
spawner: impl Fn(BoxFuture<'static, ()>) -> (),
|
||||||
) -> ClientResult<BabeImportQueue<Block, sp_api::TransactionFor<Client, Block>>> where
|
) -> ClientResult<BabeImportQueue<Block, sp_api::TransactionFor<Client, Block>>> where
|
||||||
Inner: BlockImport<Block, Error = ConsensusError, Transaction = sp_api::TransactionFor<Client, Block>>
|
Inner: BlockImport<Block, Error = ConsensusError, Transaction = sp_api::TransactionFor<Client, Block>>
|
||||||
+ Send + Sync + 'static,
|
+ Send + Sync + 'static,
|
||||||
@@ -1294,6 +1295,7 @@ pub fn import_queue<Block: BlockT, Client, Inner>(
|
|||||||
Box::new(block_import),
|
Box::new(block_import),
|
||||||
justification_import,
|
justification_import,
|
||||||
finality_proof_import,
|
finality_proof_import,
|
||||||
|
spawner,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
//! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks.
|
//! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks.
|
||||||
//! This is suitable for a testing environment.
|
//! This is suitable for a testing environment.
|
||||||
|
|
||||||
use futures::prelude::*;
|
use futures::{prelude::*, future::BoxFuture};
|
||||||
use sp_consensus::{
|
use sp_consensus::{
|
||||||
Environment, Proposer, ForkChoiceStrategy, BlockImportParams, BlockOrigin, SelectChain,
|
Environment, Proposer, ForkChoiceStrategy, BlockImportParams, BlockOrigin, SelectChain,
|
||||||
import_queue::{BasicQueue, CacheKeyId, Verifier, BoxBlockImport},
|
import_queue::{BasicQueue, CacheKeyId, Verifier, BoxBlockImport},
|
||||||
@@ -67,7 +67,8 @@ impl<B: BlockT> Verifier<B> for ManualSealVerifier {
|
|||||||
|
|
||||||
/// Instantiate the import queue for the manual seal consensus engine.
|
/// Instantiate the import queue for the manual seal consensus engine.
|
||||||
pub fn import_queue<Block, B>(
|
pub fn import_queue<Block, B>(
|
||||||
block_import: BoxBlockImport<Block, TransactionFor<B, Block>>
|
block_import: BoxBlockImport<Block, TransactionFor<B, Block>>,
|
||||||
|
spawner: impl Fn(BoxFuture<'static, ()>) -> ()
|
||||||
) -> BasicQueue<Block, TransactionFor<B, Block>>
|
) -> BasicQueue<Block, TransactionFor<B, Block>>
|
||||||
where
|
where
|
||||||
Block: BlockT,
|
Block: BlockT,
|
||||||
@@ -78,6 +79,7 @@ pub fn import_queue<Block, B>(
|
|||||||
Box::new(block_import),
|
Box::new(block_import),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
spawner,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ use codec::{Encode, Decode};
|
|||||||
use sc_client_api;
|
use sc_client_api;
|
||||||
use log::*;
|
use log::*;
|
||||||
use sp_timestamp::{InherentError as TIError, TimestampInherentData};
|
use sp_timestamp::{InherentError as TIError, TimestampInherentData};
|
||||||
|
use futures::future::BoxFuture;
|
||||||
|
|
||||||
#[derive(derive_more::Display, Debug)]
|
#[derive(derive_more::Display, Debug)]
|
||||||
pub enum Error<B: BlockT> {
|
pub enum Error<B: BlockT> {
|
||||||
@@ -461,6 +462,7 @@ pub fn import_queue<B, Transaction, Algorithm>(
|
|||||||
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
inherent_data_providers: InherentDataProviders,
|
inherent_data_providers: InherentDataProviders,
|
||||||
|
spawner: impl Fn(BoxFuture<'static, ()>) -> (),
|
||||||
) -> Result<
|
) -> Result<
|
||||||
PowImportQueue<B, Transaction>,
|
PowImportQueue<B, Transaction>,
|
||||||
sp_consensus::Error
|
sp_consensus::Error
|
||||||
@@ -477,7 +479,8 @@ pub fn import_queue<B, Transaction, Algorithm>(
|
|||||||
verifier,
|
verifier,
|
||||||
block_import,
|
block_import,
|
||||||
justification_import,
|
justification_import,
|
||||||
finality_proof_import
|
finality_proof_import,
|
||||||
|
spawner,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,11 +80,15 @@ fn build_test_full_node(config: config::NetworkConfiguration)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let threads_pool = futures::executor::ThreadPool::new().unwrap();
|
||||||
|
let spawner = |future| threads_pool.spawn_ok(future);
|
||||||
|
|
||||||
let import_queue = Box::new(sp_consensus::import_queue::BasicQueue::new(
|
let import_queue = Box::new(sp_consensus::import_queue::BasicQueue::new(
|
||||||
PassThroughVerifier(false),
|
PassThroughVerifier(false),
|
||||||
Box::new(client.clone()),
|
Box::new(client.clone()),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
spawner,
|
||||||
));
|
));
|
||||||
|
|
||||||
let worker = NetworkWorker::new(config::Params {
|
let worker = NetworkWorker::new(config::Params {
|
||||||
|
|||||||
@@ -84,7 +84,10 @@ fn async_import_queue_drops() {
|
|||||||
// Perform this test multiple times since it exhibits non-deterministic behavior.
|
// Perform this test multiple times since it exhibits non-deterministic behavior.
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
let verifier = PassThroughVerifier(true);
|
let verifier = PassThroughVerifier(true);
|
||||||
let queue = BasicQueue::new(verifier, Box::new(substrate_test_runtime_client::new()), None, None);
|
|
||||||
|
let threads_pool = futures::executor::ThreadPool::new().unwrap();
|
||||||
|
let spawner = |future| threads_pool.spawn_ok(future);
|
||||||
|
let queue = BasicQueue::new(verifier, Box::new(substrate_test_runtime_client::new()), None, None, spawner);
|
||||||
drop(queue);
|
drop(queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -606,11 +606,15 @@ pub trait TestNetFactory: Sized {
|
|||||||
);
|
);
|
||||||
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
||||||
|
|
||||||
|
let threads_pool = futures::executor::ThreadPool::new().unwrap();
|
||||||
|
let spawner = |future| threads_pool.spawn_ok(future);
|
||||||
|
|
||||||
let import_queue = Box::new(BasicQueue::new(
|
let import_queue = Box::new(BasicQueue::new(
|
||||||
verifier.clone(),
|
verifier.clone(),
|
||||||
Box::new(block_import.clone()),
|
Box::new(block_import.clone()),
|
||||||
justification_import,
|
justification_import,
|
||||||
finality_proof_import,
|
finality_proof_import,
|
||||||
|
spawner,
|
||||||
));
|
));
|
||||||
|
|
||||||
let listen_addr = build_multiaddr![Memory(rand::random::<u64>())];
|
let listen_addr = build_multiaddr![Memory(rand::random::<u64>())];
|
||||||
@@ -683,11 +687,15 @@ pub trait TestNetFactory: Sized {
|
|||||||
);
|
);
|
||||||
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
||||||
|
|
||||||
|
let threads_pool = futures::executor::ThreadPool::new().unwrap();
|
||||||
|
let spawner = |future| threads_pool.spawn_ok(future);
|
||||||
|
|
||||||
let import_queue = Box::new(BasicQueue::new(
|
let import_queue = Box::new(BasicQueue::new(
|
||||||
verifier.clone(),
|
verifier.clone(),
|
||||||
Box::new(block_import.clone()),
|
Box::new(block_import.clone()),
|
||||||
justification_import,
|
justification_import,
|
||||||
finality_proof_import,
|
finality_proof_import,
|
||||||
|
spawner,
|
||||||
));
|
));
|
||||||
|
|
||||||
let listen_addr = build_multiaddr![Memory(rand::random::<u64>())];
|
let listen_addr = build_multiaddr![Memory(rand::random::<u64>())];
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm};
|
use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm};
|
||||||
use crate::{start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager};
|
use crate::{start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager, SpawnTaskHandle};
|
||||||
use crate::status_sinks;
|
use crate::status_sinks;
|
||||||
use crate::config::{Configuration, KeystoreConfig, PrometheusConfig, OffchainWorkerConfig};
|
use crate::config::{Configuration, KeystoreConfig, PrometheusConfig, OffchainWorkerConfig};
|
||||||
use crate::metrics::MetricsService;
|
use crate::metrics::MetricsService;
|
||||||
@@ -97,7 +97,7 @@ pub struct ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
|
|||||||
remote_backend: Option<Arc<dyn RemoteBlockchain<TBl>>>,
|
remote_backend: Option<Arc<dyn RemoteBlockchain<TBl>>>,
|
||||||
marker: PhantomData<(TBl, TRtApi)>,
|
marker: PhantomData<(TBl, TRtApi)>,
|
||||||
background_tasks: Vec<(&'static str, BackgroundTask)>,
|
background_tasks: Vec<(&'static str, BackgroundTask)>,
|
||||||
block_announce_validator_builder: Option<Box<dyn FnOnce(Arc<TCl>) -> Box<dyn BlockAnnounceValidator<TBl> + Send>>>,
|
block_announce_validator_builder: Option<Box<dyn FnOnce(Arc<TCl>) -> Box<dyn BlockAnnounceValidator<TBl> + Send> + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Full client type.
|
/// Full client type.
|
||||||
@@ -487,7 +487,7 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
/// Defines which import queue to use.
|
/// Defines which import queue to use.
|
||||||
pub fn with_import_queue<UImpQu>(
|
pub fn with_import_queue<UImpQu>(
|
||||||
self,
|
self,
|
||||||
builder: impl FnOnce(&Configuration, Arc<TCl>, Option<TSc>, Arc<TExPool>)
|
builder: impl FnOnce(&Configuration, Arc<TCl>, Option<TSc>, Arc<TExPool>, &SpawnTaskHandle)
|
||||||
-> Result<UImpQu, Error>
|
-> Result<UImpQu, Error>
|
||||||
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
|
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, TFprb, TFpp,
|
||||||
TExPool, TRpc, Backend>, Error>
|
TExPool, TRpc, Backend>, Error>
|
||||||
@@ -496,7 +496,8 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
&self.config,
|
&self.config,
|
||||||
self.client.clone(),
|
self.client.clone(),
|
||||||
self.select_chain.clone(),
|
self.select_chain.clone(),
|
||||||
self.transaction_pool.clone()
|
self.transaction_pool.clone(),
|
||||||
|
&self.task_manager.spawn_handle(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(ServiceBuilder {
|
Ok(ServiceBuilder {
|
||||||
@@ -588,6 +589,7 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
Option<TFchr>,
|
Option<TFchr>,
|
||||||
Option<TSc>,
|
Option<TSc>,
|
||||||
Arc<TExPool>,
|
Arc<TExPool>,
|
||||||
|
&SpawnTaskHandle,
|
||||||
) -> Result<(UImpQu, Option<UFprb>), Error>
|
) -> Result<(UImpQu, Option<UFprb>), Error>
|
||||||
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
|
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
|
||||||
TExPool, TRpc, Backend>, Error>
|
TExPool, TRpc, Backend>, Error>
|
||||||
@@ -598,7 +600,8 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
self.backend.clone(),
|
self.backend.clone(),
|
||||||
self.fetcher.clone(),
|
self.fetcher.clone(),
|
||||||
self.select_chain.clone(),
|
self.select_chain.clone(),
|
||||||
self.transaction_pool.clone()
|
self.transaction_pool.clone(),
|
||||||
|
&self.task_manager.spawn_handle(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(ServiceBuilder {
|
Ok(ServiceBuilder {
|
||||||
@@ -631,12 +634,13 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
Option<TFchr>,
|
Option<TFchr>,
|
||||||
Option<TSc>,
|
Option<TSc>,
|
||||||
Arc<TExPool>,
|
Arc<TExPool>,
|
||||||
|
&SpawnTaskHandle,
|
||||||
) -> Result<(UImpQu, UFprb), Error>
|
) -> Result<(UImpQu, UFprb), Error>
|
||||||
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
|
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, UImpQu, UFprb, TFpp,
|
||||||
TExPool, TRpc, Backend>, Error>
|
TExPool, TRpc, Backend>, Error>
|
||||||
where TSc: Clone, TFchr: Clone {
|
where TSc: Clone, TFchr: Clone {
|
||||||
self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx|
|
self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx, tb|
|
||||||
builder(cfg, cl, b, f, sc, tx)
|
builder(cfg, cl, b, f, sc, tx, tb)
|
||||||
.map(|(q, f)| (q, Some(f)))
|
.map(|(q, f)| (q, Some(f)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -718,7 +722,7 @@ impl<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend>
|
|||||||
pub fn with_block_announce_validator(
|
pub fn with_block_announce_validator(
|
||||||
self,
|
self,
|
||||||
block_announce_validator_builder:
|
block_announce_validator_builder:
|
||||||
impl FnOnce(Arc<TCl>) -> Box<dyn BlockAnnounceValidator<TBl> + Send> + 'static,
|
impl FnOnce(Arc<TCl>) -> Box<dyn BlockAnnounceValidator<TBl> + Send> + Send + 'static,
|
||||||
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
|
) -> Result<ServiceBuilder<TBl, TRtApi, TCl, TFchr, TSc, TImpQu, TFprb, TFpp,
|
||||||
TExPool, TRpc, Backend>, Error>
|
TExPool, TRpc, Backend>, Error>
|
||||||
where TSc: Clone, TFchr: Clone {
|
where TSc: Clone, TFchr: Clone {
|
||||||
|
|||||||
@@ -56,12 +56,13 @@ impl<
|
|||||||
TExecDisp: 'static + NativeExecutionDispatch,
|
TExecDisp: 'static + NativeExecutionDispatch,
|
||||||
TImpQu: 'static + ImportQueue<TBl>,
|
TImpQu: 'static + ImportQueue<TBl>,
|
||||||
TRtApi: 'static + Send + Sync,
|
TRtApi: 'static + Send + Sync,
|
||||||
|
Self: Send + 'static,
|
||||||
{
|
{
|
||||||
type Block = TBl;
|
type Block = TBl;
|
||||||
type NativeDispatch = TExecDisp;
|
type NativeDispatch = TExecDisp;
|
||||||
|
|
||||||
fn import_blocks(
|
fn import_blocks(
|
||||||
self,
|
mut self,
|
||||||
input: impl Read + Seek + Send + 'static,
|
input: impl Read + Seek + Send + 'static,
|
||||||
force: bool,
|
force: bool,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send>> {
|
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send>> {
|
||||||
@@ -98,9 +99,6 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = self.client;
|
|
||||||
let mut queue = self.import_queue;
|
|
||||||
|
|
||||||
let mut io_reader_input = IoReader(input);
|
let mut io_reader_input = IoReader(input);
|
||||||
let mut count = None::<u64>;
|
let mut count = None::<u64>;
|
||||||
let mut read_block_count = 0;
|
let mut read_block_count = 0;
|
||||||
@@ -114,6 +112,9 @@ impl<
|
|||||||
// This makes it possible either to interleave other operations in-between the block imports,
|
// This makes it possible either to interleave other operations in-between the block imports,
|
||||||
// or to stop the operation completely.
|
// or to stop the operation completely.
|
||||||
let import = future::poll_fn(move |cx| {
|
let import = future::poll_fn(move |cx| {
|
||||||
|
let client = &self.client;
|
||||||
|
let queue = &mut self.import_queue;
|
||||||
|
|
||||||
// Start by reading the number of blocks if not done so already.
|
// Start by reading the number of blocks if not done so already.
|
||||||
let count = match count {
|
let count = match count {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
@@ -203,13 +204,12 @@ impl<
|
|||||||
to: Option<NumberFor<TBl>>,
|
to: Option<NumberFor<TBl>>,
|
||||||
binary: bool
|
binary: bool
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), Error>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<(), Error>>>> {
|
||||||
let client = self.client;
|
|
||||||
let mut block = from;
|
let mut block = from;
|
||||||
|
|
||||||
let last = match to {
|
let last = match to {
|
||||||
Some(v) if v.is_zero() => One::one(),
|
Some(v) if v.is_zero() => One::one(),
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => client.chain_info().best_number,
|
None => self.client.chain_info().best_number,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut wrote_header = false;
|
let mut wrote_header = false;
|
||||||
@@ -222,6 +222,8 @@ impl<
|
|||||||
// This makes it possible either to interleave other operations in-between the block exports,
|
// This makes it possible either to interleave other operations in-between the block exports,
|
||||||
// or to stop the operation completely.
|
// or to stop the operation completely.
|
||||||
let export = future::poll_fn(move |cx| {
|
let export = future::poll_fn(move |cx| {
|
||||||
|
let client = &self.client;
|
||||||
|
|
||||||
if last < block {
|
if last < block {
|
||||||
return std::task::Poll::Ready(Err("Invalid block range specified".into()));
|
return std::task::Poll::Ready(Err("Invalid block range specified".into()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ pub struct Configuration {
|
|||||||
/// Node role.
|
/// Node role.
|
||||||
pub role: Role,
|
pub role: Role,
|
||||||
/// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error.
|
/// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error.
|
||||||
pub task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + Sync>,
|
pub task_executor: Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>, TaskType) + Send + Sync>,
|
||||||
/// Extrinsic pool configuration.
|
/// Extrinsic pool configuration.
|
||||||
pub transaction_pool: TransactionPoolOptions,
|
pub transaction_pool: TransactionPoolOptions,
|
||||||
/// Network configuration.
|
/// Network configuration.
|
||||||
@@ -102,6 +102,15 @@ pub struct Configuration {
|
|||||||
pub announce_block: bool,
|
pub announce_block: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type for tasks spawned by the executor.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum TaskType {
|
||||||
|
/// Regular non-blocking futures. Polling the task is expected to be a lightweight operation.
|
||||||
|
Async,
|
||||||
|
/// The task might perform a lot of expensive CPU operations and/or call `thread::sleep`.
|
||||||
|
Blocking,
|
||||||
|
}
|
||||||
|
|
||||||
/// Configuration of the client keystore.
|
/// Configuration of the client keystore.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum KeystoreConfig {
|
pub enum KeystoreConfig {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ pub use self::builder::{
|
|||||||
ServiceBuilder, ServiceBuilderCommand, TFullClient, TLightClient, TFullBackend, TLightBackend,
|
ServiceBuilder, ServiceBuilderCommand, TFullClient, TLightClient, TFullBackend, TLightBackend,
|
||||||
TFullCallExecutor, TLightCallExecutor,
|
TFullCallExecutor, TLightCallExecutor,
|
||||||
};
|
};
|
||||||
pub use config::{Configuration, Role, PruningMode, DatabaseConfig};
|
pub use config::{Configuration, Role, PruningMode, DatabaseConfig, TaskType};
|
||||||
pub use sc_chain_spec::{
|
pub use sc_chain_spec::{
|
||||||
ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension,
|
ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension,
|
||||||
NoExtension, ChainType,
|
NoExtension, ChainType,
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ use prometheus_endpoint::{
|
|||||||
CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64
|
CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64
|
||||||
};
|
};
|
||||||
use sc_client_api::CloneableSpawn;
|
use sc_client_api::CloneableSpawn;
|
||||||
|
use crate::config::TaskType;
|
||||||
|
|
||||||
mod prometheus_future;
|
mod prometheus_future;
|
||||||
|
|
||||||
/// Type alias for service task executor (usually runtime).
|
/// Type alias for service task executor (usually runtime).
|
||||||
pub type ServiceTaskExecutor = Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + Sync>;
|
pub type ServiceTaskExecutor = Arc<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>, TaskType) + Send + Sync>;
|
||||||
|
|
||||||
/// An handle for spawning tasks in the service.
|
/// An handle for spawning tasks in the service.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -55,6 +56,16 @@ impl SpawnTaskHandle {
|
|||||||
/// In other words, it would be a bad idea for someone to do for example
|
/// In other words, it would be a bad idea for someone to do for example
|
||||||
/// `spawn(format!("{:?}", some_public_key))`.
|
/// `spawn(format!("{:?}", some_public_key))`.
|
||||||
pub fn spawn(&self, name: &'static str, task: impl Future<Output = ()> + Send + 'static) {
|
pub fn spawn(&self, name: &'static str, task: impl Future<Output = ()> + Send + 'static) {
|
||||||
|
self.spawn_inner(name, task, TaskType::Async)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Spawns the blocking task with the given name. See also `spawn`.
|
||||||
|
pub fn spawn_blocking(&self, name: &'static str, task: impl Future<Output = ()> + Send + 'static) {
|
||||||
|
self.spawn_inner(name, task, TaskType::Blocking)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function that implements the spawning logic. See `spawn` and `spawn_blocking`.
|
||||||
|
fn spawn_inner(&self, name: &'static str, task: impl Future<Output = ()> + Send + 'static, task_type: TaskType) {
|
||||||
let on_exit = self.on_exit.clone();
|
let on_exit = self.on_exit.clone();
|
||||||
let metrics = self.metrics.clone();
|
let metrics = self.metrics.clone();
|
||||||
|
|
||||||
@@ -80,7 +91,7 @@ impl SpawnTaskHandle {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(self.executor)(Box::pin(future));
|
(self.executor)(Box::pin(future), task_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ use sc_service::{
|
|||||||
RuntimeGenesis,
|
RuntimeGenesis,
|
||||||
Role,
|
Role,
|
||||||
Error,
|
Error,
|
||||||
|
TaskType,
|
||||||
};
|
};
|
||||||
use sp_blockchain::HeaderBackend;
|
use sp_blockchain::HeaderBackend;
|
||||||
use sc_network::{multiaddr, Multiaddr};
|
use sc_network::{multiaddr, Multiaddr};
|
||||||
@@ -139,7 +140,7 @@ fn node_config<G: RuntimeGenesis + 'static, E: ChainSpecExtension + Clone + 'sta
|
|||||||
index: usize,
|
index: usize,
|
||||||
spec: &GenericChainSpec<G, E>,
|
spec: &GenericChainSpec<G, E>,
|
||||||
role: Role,
|
role: Role,
|
||||||
task_executor: Arc<dyn Fn(Pin<Box<dyn futures::Future<Output = ()> + Send>>) + Send + Sync>,
|
task_executor: Arc<dyn Fn(Pin<Box<dyn futures::Future<Output = ()> + Send>>, TaskType) + Send + Sync>,
|
||||||
key_seed: Option<String>,
|
key_seed: Option<String>,
|
||||||
base_port: u16,
|
base_port: u16,
|
||||||
root: &TempDir,
|
root: &TempDir,
|
||||||
@@ -255,7 +256,7 @@ impl<G, E, F, L, U> TestNet<G, E, F, L, U> where
|
|||||||
for (key, authority) in authorities {
|
for (key, authority) in authorities {
|
||||||
let task_executor = {
|
let task_executor = {
|
||||||
let executor = executor.clone();
|
let executor = executor.clone();
|
||||||
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>| executor.spawn(fut.unit_error().compat()))
|
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>, _| executor.spawn(fut.unit_error().compat()))
|
||||||
};
|
};
|
||||||
let node_config = node_config(
|
let node_config = node_config(
|
||||||
self.nodes,
|
self.nodes,
|
||||||
@@ -279,7 +280,7 @@ impl<G, E, F, L, U> TestNet<G, E, F, L, U> where
|
|||||||
for full in full {
|
for full in full {
|
||||||
let task_executor = {
|
let task_executor = {
|
||||||
let executor = executor.clone();
|
let executor = executor.clone();
|
||||||
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>| executor.spawn(fut.unit_error().compat()))
|
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>, _| executor.spawn(fut.unit_error().compat()))
|
||||||
};
|
};
|
||||||
let node_config = node_config(self.nodes, &self.chain_spec, Role::Full, task_executor, None, self.base_port, &temp);
|
let node_config = node_config(self.nodes, &self.chain_spec, Role::Full, task_executor, None, self.base_port, &temp);
|
||||||
let addr = node_config.network.listen_addresses.iter().next().unwrap().clone();
|
let addr = node_config.network.listen_addresses.iter().next().unwrap().clone();
|
||||||
@@ -295,7 +296,7 @@ impl<G, E, F, L, U> TestNet<G, E, F, L, U> where
|
|||||||
for light in light {
|
for light in light {
|
||||||
let task_executor = {
|
let task_executor = {
|
||||||
let executor = executor.clone();
|
let executor = executor.clone();
|
||||||
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>| executor.spawn(fut.unit_error().compat()))
|
Arc::new(move |fut: Pin<Box<dyn futures::Future<Output = ()> + Send>>, _| executor.spawn(fut.unit_error().compat()))
|
||||||
};
|
};
|
||||||
let node_config = node_config(self.nodes, &self.chain_spec, Role::Light, task_executor, None, self.base_port, &temp);
|
let node_config = node_config(self.nodes, &self.chain_spec, Role::Light, task_executor, None, self.base_port, &temp);
|
||||||
let addr = node_config.network.listen_addresses.iter().next().unwrap().clone();
|
let addr = node_config.network.listen_addresses.iter().next().unwrap().clone();
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ sp-inherents = { version = "2.0.0-dev", path = "../../inherents" }
|
|||||||
sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" }
|
sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" }
|
||||||
futures = { version = "0.3.1", features = ["thread-pool"] }
|
futures = { version = "0.3.1", features = ["thread-pool"] }
|
||||||
futures-timer = "3.0.1"
|
futures-timer = "3.0.1"
|
||||||
futures-diagnose = "1.0"
|
|
||||||
sp-std = { version = "2.0.0-dev", path = "../../std" }
|
sp-std = { version = "2.0.0-dev", path = "../../std" }
|
||||||
sp-version = { version = "2.0.0-dev", path = "../../version" }
|
sp-version = { version = "2.0.0-dev", path = "../../version" }
|
||||||
sp-runtime = { version = "2.0.0-dev", path = "../../runtime" }
|
sp-runtime = { version = "2.0.0-dev", path = "../../runtime" }
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::{mem, pin::Pin, time::Duration, marker::PhantomData, sync::Arc};
|
use std::{mem, pin::Pin, time::Duration, marker::PhantomData};
|
||||||
use futures::{prelude::*, task::Context, task::Poll};
|
use futures::{prelude::*, task::Context, task::Poll, future::BoxFuture};
|
||||||
use futures_timer::Delay;
|
use futures_timer::Delay;
|
||||||
use parking_lot::{Mutex, Condvar};
|
|
||||||
use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}};
|
use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}};
|
||||||
use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded};
|
use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded};
|
||||||
|
|
||||||
@@ -36,31 +35,14 @@ pub struct BasicQueue<B: BlockT, Transaction> {
|
|||||||
sender: TracingUnboundedSender<ToWorkerMsg<B>>,
|
sender: TracingUnboundedSender<ToWorkerMsg<B>>,
|
||||||
/// Results coming from the worker task.
|
/// Results coming from the worker task.
|
||||||
result_port: BufferedLinkReceiver<B>,
|
result_port: BufferedLinkReceiver<B>,
|
||||||
/// If it isn't possible to spawn the future in `future_to_spawn` (which is notably the case in
|
|
||||||
/// "no std" environment), we instead put it in `manual_poll`. It is then polled manually from
|
|
||||||
/// `poll_actions`.
|
|
||||||
manual_poll: Option<Pin<Box<dyn Future<Output = ()> + Send>>>,
|
|
||||||
/// A thread pool where the background worker is being run.
|
|
||||||
pool: Option<futures::executor::ThreadPool>,
|
|
||||||
pool_guard: Arc<(Mutex<usize>, Condvar)>,
|
|
||||||
_phantom: PhantomData<Transaction>,
|
_phantom: PhantomData<Transaction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT, Transaction> Drop for BasicQueue<B, Transaction> {
|
impl<B: BlockT, Transaction> Drop for BasicQueue<B, Transaction> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.pool = None;
|
|
||||||
// Flush the queue and close the receiver to terminate the future.
|
// Flush the queue and close the receiver to terminate the future.
|
||||||
self.sender.close_channel();
|
self.sender.close_channel();
|
||||||
self.result_port.close();
|
self.result_port.close();
|
||||||
|
|
||||||
// Make sure all pool threads terminate.
|
|
||||||
// https://github.com/rust-lang/futures-rs/issues/1470
|
|
||||||
// https://github.com/rust-lang/futures-rs/issues/1349
|
|
||||||
let (ref mutex, ref condvar) = *self.pool_guard;
|
|
||||||
let mut lock = mutex.lock();
|
|
||||||
while *lock != 0 {
|
|
||||||
condvar.wait(&mut lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +56,7 @@ impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
|
|||||||
block_import: BoxBlockImport<B, Transaction>,
|
block_import: BoxBlockImport<B, Transaction>,
|
||||||
justification_import: Option<BoxJustificationImport<B>>,
|
justification_import: Option<BoxJustificationImport<B>>,
|
||||||
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
finality_proof_import: Option<BoxFinalityProofImport<B>>,
|
||||||
|
spawner: impl Fn(BoxFuture<'static, ()>) -> (),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (result_sender, result_port) = buffered_link::buffered_link();
|
let (result_sender, result_port) = buffered_link::buffered_link();
|
||||||
let (future, worker_sender) = BlockImportWorker::new(
|
let (future, worker_sender) = BlockImportWorker::new(
|
||||||
@@ -84,39 +67,11 @@ impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
|
|||||||
finality_proof_import,
|
finality_proof_import,
|
||||||
);
|
);
|
||||||
|
|
||||||
let guard = Arc::new((Mutex::new(0usize), Condvar::new()));
|
spawner(future.boxed());
|
||||||
let guard_start = guard.clone();
|
|
||||||
let guard_end = guard.clone();
|
|
||||||
|
|
||||||
let mut pool = futures::executor::ThreadPool::builder()
|
|
||||||
.name_prefix("import-queue-worker-")
|
|
||||||
.pool_size(1)
|
|
||||||
.after_start(move |_| *guard_start.0.lock() += 1)
|
|
||||||
.before_stop(move |_| {
|
|
||||||
let (ref mutex, ref condvar) = *guard_end;
|
|
||||||
let mut lock = mutex.lock();
|
|
||||||
*lock -= 1;
|
|
||||||
if *lock == 0 {
|
|
||||||
condvar.notify_one();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.create()
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let manual_poll;
|
|
||||||
if let Some(pool) = &mut pool {
|
|
||||||
pool.spawn_ok(futures_diagnose::diagnose("import-queue", future));
|
|
||||||
manual_poll = None;
|
|
||||||
} else {
|
|
||||||
manual_poll = Some(Box::pin(future) as Pin<Box<_>>);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
sender: worker_sender,
|
sender: worker_sender,
|
||||||
result_port,
|
result_port,
|
||||||
manual_poll,
|
|
||||||
pool,
|
|
||||||
pool_guard: guard,
|
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,15 +115,6 @@ impl<B: BlockT, Transaction: Send> ImportQueue<B> for BasicQueue<B, Transaction>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link<B>) {
|
fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link<B>) {
|
||||||
// As a backup mechanism, if we failed to spawn the `future_to_spawn`, we instead poll
|
|
||||||
// manually here.
|
|
||||||
if let Some(manual_poll) = self.manual_poll.as_mut() {
|
|
||||||
match Future::poll(Pin::new(manual_poll), cx) {
|
|
||||||
Poll::Pending => {}
|
|
||||||
_ => self.manual_poll = None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.result_port.poll_actions(cx, link);
|
self.result_port.poll_actions(cx, link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ where
|
|||||||
network,
|
network,
|
||||||
telemetry_endpoints: chain_spec.telemetry_endpoints().clone(),
|
telemetry_endpoints: chain_spec.telemetry_endpoints().clone(),
|
||||||
chain_spec: Box::new(chain_spec),
|
chain_spec: Box::new(chain_spec),
|
||||||
task_executor: Arc::new(move |fut| wasm_bindgen_futures::spawn_local(fut)),
|
task_executor: Arc::new(move |fut, _| wasm_bindgen_futures::spawn_local(fut)),
|
||||||
telemetry_external_transport: Some(transport),
|
telemetry_external_transport: Some(transport),
|
||||||
role: Role::Light,
|
role: Role::Light,
|
||||||
database: {
|
database: {
|
||||||
|
|||||||
Reference in New Issue
Block a user