Skip to main content

bark_runtime/
task.rs

1use std::future::Future;
2
3use crate::MaybeSend;
4
5/// Spawn a task on the current runtime.
6///
7/// On native platforms, uses `tokio::spawn`.
8/// On WASM, uses `wasm_bindgen_futures::spawn_local`.
9pub fn spawn<F>(future: F)
10where
11	F: Future<Output = ()> + MaybeSend + 'static,
12{
13	#[cfg(not(target_arch = "wasm32"))]
14	tokio::spawn(future);
15
16	#[cfg(target_arch = "wasm32")]
17	wasm_bindgen_futures::spawn_local(future);
18}
19
20#[cfg(test)]
21mod test {
22	use std::time::Duration;
23
24	use tokio::sync::{mpsc, oneshot};
25
26	use crate::timeout;
27
28	use super::*;
29
30	#[cfg(target_arch = "wasm32")]
31	use wasm_bindgen_test::wasm_bindgen_test;
32	#[cfg(target_arch = "wasm32")]
33	wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
34
35	/// A spawned task runs and its result reaches the spawner.
36	#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
37	#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
38	async fn spawned_task_runs() {
39		let (tx, rx) = oneshot::channel();
40		spawn(async move {
41			tx.send(42).unwrap();
42		});
43
44		let received = timeout(Duration::from_secs(5), rx).await
45			.expect("the spawned task should have sent its value")
46			.expect("the sender should not have been dropped");
47		assert_eq!(42, received);
48	}
49
50	/// A spawned task keeps running after an await point.
51	#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
52	#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
53	async fn spawned_task_continues_after_awaiting() {
54		let (tx, mut rx) = mpsc::channel(2);
55		spawn(async move {
56			tx.send(1).await.unwrap();
57			crate::sleep(Duration::from_millis(10)).await;
58			tx.send(2).await.unwrap();
59		});
60
61		assert_eq!(Some(1), rx.recv().await);
62		assert_eq!(Some(2), rx.recv().await);
63	}
64
65	/// Several spawned tasks all run.
66	#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
67	#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
68	async fn all_spawned_tasks_run() {
69		let (tx, mut rx) = mpsc::channel(3);
70		for i in 0..3 {
71			let tx = tx.clone();
72			spawn(async move {
73				tx.send(i).await.unwrap();
74			});
75		}
76		drop(tx);
77
78		let mut received = Vec::new();
79		while let Some(i) = rx.recv().await {
80			received.push(i);
81		}
82		received.sort();
83		assert_eq!(vec![0, 1, 2], received);
84	}
85}
86