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::*;