Skip to main content

cdk_common/
task.rs

1//! Thin wrapper for spawn and spawn_local for native and wasm.
2
3use std::future::Future;
4#[cfg(not(target_arch = "wasm32"))]
5use std::sync::OnceLock;
6
7use tokio::task::JoinHandle;
8
9#[cfg(not(target_arch = "wasm32"))]
10static GLOBAL_RUNTIME: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
11
12/// Spawns a new asynchronous task returning nothing
13///
14/// # Panics
15///
16/// Panics if the global Tokio runtime cannot be created when no runtime exists on the current thread.
17#[cfg(not(target_arch = "wasm32"))]
18pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
19where
20    F: Future + Send + 'static,
21    F::Output: Send + 'static,
22{
23    if let Ok(handle) = tokio::runtime::Handle::try_current() {
24        handle.spawn(future)
25    } else {
26        // No runtime on this thread (FFI/regular sync context):
27        // use (or lazily create) a global runtime and spawn on it.
28        GLOBAL_RUNTIME
29            .get_or_init(|| {
30                tokio::runtime::Builder::new_multi_thread()
31                    .enable_all()
32                    .build()
33                    .expect("failed to build global Tokio runtime")
34            })
35            .spawn(future)
36    }
37}
38
39/// Spawns a new asynchronous task returning nothing
40#[cfg(target_arch = "wasm32")]
41pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
42where
43    F: Future + 'static,
44    F::Output: 'static,
45{
46    tokio::task::spawn_local(future)
47}