From c849ef3cf4ac639673a408e8ffb135b2f9a17c85 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sat, 5 Jan 2019 14:34:50 +0000 Subject: [PATCH 1/4] Add naive spawn_local implementation + tests This is just a naive implementation. It seems it can be improved using a custom task queue, but that can be in a separate PR. --- crates/futures/src/lib.rs | 12 ++++++++++++ crates/futures/tests/tests.rs | 20 +++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs index 7bd5c9b207b..3711a66662b 100644 --- a/crates/futures/src/lib.rs +++ b/crates/futures/src/lib.rs @@ -377,3 +377,15 @@ fn _future_to_promise(future: Box>) -> P } } } + +/// Spawns a future. +pub fn spawn_local(future: F) +where + F: Future + 'static, +{ + future_to_promise( + future + .map(|_| JsValue::undefined()) + .map_err(|_| JsValue::undefined()), + ); +} diff --git a/crates/futures/tests/tests.rs b/crates/futures/tests/tests.rs index 87d8a1f46fb..7b76dfe5b2a 100644 --- a/crates/futures/tests/tests.rs +++ b/crates/futures/tests/tests.rs @@ -9,7 +9,7 @@ extern crate wasm_bindgen_test; use futures::unsync::oneshot; use futures::Future; use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::{future_to_promise, JsFuture}; +use wasm_bindgen_futures::{future_to_promise, spawn_local, JsFuture}; use wasm_bindgen_test::*; #[wasm_bindgen_test(async)] @@ -68,3 +68,21 @@ fn oneshot_works() -> impl Future { closure.forget(); rx.then(|_| Ok(())) } + +#[wasm_bindgen_test(async)] +fn spawn_local_runs() -> impl Future { + let (tx, rx) = oneshot::channel::(); + let fn_box = Box::new(move || { + tx.send(42).unwrap(); + }); + spawn_local(futures::future::ok::<(), ()>(()).map(|_| { + fn_box(); + })); + rx.then(|val| { + if val == Ok(42) { + Ok(()) + } else { + Err(JsValue::undefined()) + } + }) +} From 25ac4549a08ac2a0b56c74b1030a7f88b65d69e2 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sat, 5 Jan 2019 14:37:39 +0000 Subject: [PATCH 2/4] Docs --- crates/futures/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs index 3711a66662b..ca35b0aba2f 100644 --- a/crates/futures/src/lib.rs +++ b/crates/futures/src/lib.rs @@ -378,7 +378,14 @@ fn _future_to_promise(future: Box>) -> P } } -/// Spawns a future. +/// Converts a Rust `Future` on a local task queue. +/// +/// The `future` provided must adhere to `'static` because it'll be scheduled +/// to run in the background and cannot contain any stack references. +/// +/// # Panics +/// +/// This function has the same panic behavior as `future_to_promise`. pub fn spawn_local(future: F) where F: Future + 'static, From 73913c99f271cba0970a8fab8d32e128727d1def Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sat, 5 Jan 2019 18:10:14 +0000 Subject: [PATCH 3/4] Relax bound on Future --- crates/futures/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs index ca35b0aba2f..998c6878692 100644 --- a/crates/futures/src/lib.rs +++ b/crates/futures/src/lib.rs @@ -388,7 +388,7 @@ fn _future_to_promise(future: Box>) -> P /// This function has the same panic behavior as `future_to_promise`. pub fn spawn_local(future: F) where - F: Future + 'static, + F: Future + 'static, { future_to_promise( future From 687fc278a7aca25cd6e8a9c9c9115b978b48f7e1 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Mon, 7 Jan 2019 14:23:10 +0000 Subject: [PATCH 4/4] Revert previous change. --- crates/futures/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs index 998c6878692..dc1b30c797c 100644 --- a/crates/futures/src/lib.rs +++ b/crates/futures/src/lib.rs @@ -388,11 +388,11 @@ fn _future_to_promise(future: Box>) -> P /// This function has the same panic behavior as `future_to_promise`. pub fn spawn_local(future: F) where - F: Future + 'static, + F: Future + 'static, { future_to_promise( future - .map(|_| JsValue::undefined()) - .map_err(|_| JsValue::undefined()), + .map(|()| JsValue::undefined()) + .map_err(|()| JsValue::undefined()), ); }