workflow_core/task.rs
1//!
2//! [`task`](self) module provides helper functions for use with async closures that *operate uniformly*
3//! in native ([`tokio`](https://crates.io/crates/tokio)-backed) and WASM ([`async_std`]-backed) environments
4//! (i.e. a web browser).
5//!
6//! Following functions are are available:
7//! - [`spawn()`] - non-blocking spawn of the supplied async closure
8//! - [`sleep()`] - suspends the task for a given Duration
9//! - [`yield_now()`] - yields rust executor
10//! - [`yield_executor()`] - yields to top-level executor (browser async loop)
11//!
12//! <div class="example-wrap compile_fail"><pre class="compile_fail" style="white-space:normal;font:inherit;">
13//! Blocking spawn is not available as a part of this framework as WASM-browser environment can
14//! not block task execution due to a single-threaded async application environment.
15//! </pre></div>
16//!
17
18#[allow(unused_imports)]
19use cfg_if::cfg_if;
20use futures::Future;
21
22cfg_if! {
23 if #[cfg(not(any(target_arch = "wasm32", target_arch = "bpf")))] {
24
25 pub mod native {
26 //! native implementation
27 pub use super::*;
28
29 // yield_executor functionality is browser-specific
30 // hence we create a stub in a form of `yield_now()`
31 // for native platforms
32 pub use tokio::task::yield_now as yield_executor;
33 pub use tokio::task::yield_now;
34 pub use tokio::time::sleep;
35 pub use crate::native::interval::{interval,Interval};
36
37 pub fn spawn<F, T>(future: F)
38 where
39 F: Future<Output = T> + Send + 'static,
40 T: Send + 'static,
41 {
42 tokio::task::spawn(future);
43 }
44
45 pub fn dispatch<F, T>(_future: F)
46 where
47 F: Future<Output = T> + 'static,
48 T: 'static,
49 {
50 unreachable!()
51 }
52
53 pub use workflow_core_macros::call_async_no_send;
54 }
55
56 pub use native::*;
57 }
58}
59
60pub mod wasm {
61 //! WASM implementation
62 pub use super::*;
63
64 pub fn spawn<F, T>(_future: F)
65 where
66 F: Future<Output = T> + Send + 'static,
67 T: Send + 'static,
68 {
69 cfg_if::cfg_if! {
70 if #[cfg(target_arch = "wasm32")] {
71 // wasm32 spawn shim
72 // spawn and spawn_local are currently not available on wasm32 architectures
73 // ironically, block_on is but it spawns a task instead of blocking it
74 // unfortunately access to [`async_std::task::Builder::local()`] is
75 // private.
76 async_std::task::block_on(_future);
77 } else {
78 panic!("workflow_core::task::wasm::spawn() is not allowed on non-wasm target");
79 }
80 }
81 }
82
83 // `dispatch()` is similar to `spawn()` but does not
84 // impose `Send` requirement on the supplied future
85 // when building for the `wasm32` target.
86 pub fn dispatch<F, T>(_future: F)
87 where
88 F: Future<Output = T> + 'static,
89 T: 'static,
90 {
91 cfg_if::cfg_if! {
92 if #[cfg(target_arch = "wasm32")] {
93 // wasm32 spawn shim
94 // spawn and spawn_local are currently not available on wasm32 architectures
95 // ironically, block_on is but it spawns a task instead of blocking it
96 // unfortunately access to [`async_std::task::Builder::local()`] is
97 // private.
98 async_std::task::block_on(_future);
99 } else {
100 panic!("workflow_core::task::wasm::spawn() is not allowed on non-wasm target");
101 }
102 }
103 }
104
105 cfg_if! {
106 if #[cfg(target_arch = "wasm32")] {
107 pub use crate::wasm::{
108 overrides::disable_persistent_timer_overrides,
109 interval::{interval,Interval},
110 yield_executor::{yield_executor,Yield},
111 sleep::{sleep,Sleep}
112 };
113 pub use async_std::task::yield_now;
114 pub use workflow_core_macros::call_async_no_send;
115 } else {
116 pub use crate::native::{
117 overrides::disable_persistent_timer_overrides,
118 interval::{interval,Interval},
119 };
120 pub use async_std::task::sleep;
121 pub use async_std::task::yield_now;
122 pub use workflow_core_macros::call_async_no_send;
123 }
124 }
125}
126
127#[cfg(target_arch = "wasm32")]
128pub use wasm::*;