Expose that BasicQueue expects blocking spawn (#5860)

* Expose that `BasicQueue` expects blocking spawn

Up to now `BasicQueue` expected a closure that to spawn a `Future`.
This was expected to be a closure that spawns a blocking future.
However, this wasn't documented anywhere. This pr introduces a new trait
`SpawnBlocking` that exposes this requirement to the outside.

* Feedback
This commit is contained in:
Bastian Köcher
2020-05-04 19:40:29 +02:00
committed by GitHub
parent 8549cf5899
commit 9c5536e01a
15 changed files with 90 additions and 48 deletions
@@ -15,7 +15,7 @@
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use std::{mem, pin::Pin, time::Duration, marker::PhantomData};
use futures::{prelude::*, task::Context, task::Poll, future::BoxFuture};
use futures::{prelude::*, task::Context, task::Poll};
use futures_timer::Delay;
use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}};
use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded};
@@ -56,7 +56,7 @@ impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
block_import: BoxBlockImport<B, Transaction>,
justification_import: Option<BoxJustificationImport<B>>,
finality_proof_import: Option<BoxFinalityProofImport<B>>,
spawner: impl Fn(BoxFuture<'static, ()>) -> (),
spawner: &impl sp_core::traits::SpawnBlocking,
) -> Self {
let (result_sender, result_port) = buffered_link::buffered_link();
let (future, worker_sender) = BlockImportWorker::new(
@@ -67,7 +67,7 @@ impl<B: BlockT, Transaction: Send + 'static> BasicQueue<B, Transaction> {
finality_proof_import,
);
spawner(future.boxed());
spawner.spawn_blocking("basic-block-import-worker", future.boxed());
Self {
sender: worker_sender,
+24
View File
@@ -290,6 +290,30 @@ macro_rules! wasm_export_functions {
};
}
/// An executor that supports spawning blocking futures in tests.
///
/// Internally this just wraps a `ThreadPool` with a pool size of `8`. This
/// should ensure that we have enough threads in tests for spawning blocking futures.
#[cfg(feature = "std")]
#[derive(Clone)]
pub struct SpawnBlockingExecutor(futures::executor::ThreadPool);
#[cfg(feature = "std")]
impl SpawnBlockingExecutor {
/// Create a new instance of `Self`.
pub fn new() -> Self {
let mut builder = futures::executor::ThreadPoolBuilder::new();
Self(builder.pool_size(8).create().expect("Failed to create thread pool"))
}
}
#[cfg(feature = "std")]
impl crate::traits::SpawnBlocking for SpawnBlockingExecutor {
fn spawn_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) {
self.0.spawn_ok(future);
}
}
#[cfg(test)]
mod tests {
use super::*;
+8
View File
@@ -330,3 +330,11 @@ impl TaskExecutorExt {
Self(spawn_handle)
}
}
/// Something that can spawn a blocking future.
pub trait SpawnBlocking {
/// Spawn the given blocking future.
///
/// The given `name` is used to identify the future in tracing.
fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>);
}