Skip to content

Commit

Permalink
include suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
blasrodri committed Aug 25, 2020
1 parent ef1cd37 commit 8006c42
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 25 deletions.
1 change: 0 additions & 1 deletion tokio-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ log = "0.4"
pin-project-lite = "0.1.4"

[dev-dependencies]
lazy_static = "1.4.0"
tokio = { version = "0.3.0", path = "../tokio", features = ["full"] }
tokio-test = { version = "0.3.0", path = "../tokio-test" }

Expand Down
34 changes: 27 additions & 7 deletions tokio-util/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
use tokio::runtime::Handle;

pin_project! {
/// TODO: add docs. Get some inspiration?
/// TokioContext allows connecting a custom executor with the tokio runtime.
pub struct TokioContext<F> {
#[pin]
inner: F,
Expand All @@ -28,11 +28,31 @@ impl<F: Future> Future for TokioContext<F> {
handle.enter(|| fut.poll(cx))
}
}

impl<F: Future> TokioContext<F> {
/// Creates a new `TokioContext`. Expects a future as its first argument, and a
/// `tokio::runtime::Handle` as a second.
pub fn new(f: F, handle: Handle) -> Self {
Self { inner: f, handle }
/// Trait extension that simplifies bundling a `Handle` with a `Future`.
pub trait HandleExt: Into<Handle> + Clone {
/// Convenience method that takes a Future and returns a `TokioContext`.
/// # Example
/// ```rust,no_run
///
/// use std::futures::Future;
/// use tokio-utils::context::{HandleExt};
/// use tokio::runtime::Handle;
///
/// impl ThreadPool {
/// fn spawn(&self, f: impl Future<Output = ()> + Send + 'static) {
/// let handle = self.rt.handle().clone();
/// // create a TokioContext from the handle and future.
/// let h = handle.wrap(f);
/// self.inner.spawn_ok(h);
/// }
/// ```
///
fn wrap<F>(&self, fut: F) -> TokioContext<F>
where
F: Future,
{
TokioContext {inner: fut, handle: (*self).clone().into()}
}
}

impl HandleExt for Handle {}
31 changes: 14 additions & 17 deletions tokio-util/tests/context.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
#![warn(rust_2018_idioms)]

use tokio::{net::TcpListener, sync::oneshot};
use tokio_util::context::TokioContext;
use tokio_util::context::{HandleExt, TokioContext};

use lazy_static::lazy_static;
use std::future::Future;

struct ThreadPool {
inner: futures::executor::ThreadPool,
rt: tokio::runtime::Runtime,
}

lazy_static! {
static ref EXECUTOR: ThreadPool = {
impl ThreadPool {
fn spawn(&self, f: impl Future<Output = ()> + Send + 'static) {
let handle = self.rt.handle().clone();
let h: TokioContext<_> = handle.wrap(f);
self.inner.spawn_ok(h);
}
}

#[test]
fn tokio_context_with_another_runtime() {
let (tx, rx) = oneshot::channel();
let custom_executor: ThreadPool = {
// Spawn tokio runtime on a single background thread
// enabling IO and timers.
let rt = tokio::runtime::Builder::new()
Expand All @@ -26,20 +35,8 @@ lazy_static! {

ThreadPool { inner, rt }
};
}

impl ThreadPool {
fn spawn(&self, f: impl Future<Output = ()> + Send + 'static) {
let handle = self.rt.handle().clone();
self.inner.spawn_ok(TokioContext::new(f, handle));
}
}

#[test]
fn tokio_context_with_another_runtime() {
let (tx, rx) = oneshot::channel();

EXECUTOR.spawn(async move {
custom_executor.spawn(async move {
let listener = TcpListener::bind("0.0.0.0:0").await.unwrap();
println!("addr: {:?}", listener.local_addr());
tx.send(()).unwrap();
Expand Down

0 comments on commit 8006c42

Please sign in to comment.