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