linera_base/
task.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5Abstractions over tasks that can be used natively or on the Web.
6 */
7
8use std::future::Future;
9
10#[cfg(not(web))]
11mod implementation {
12    use super::*;
13
14    /// The type of errors that can result from awaiting a task to completion.
15    pub type Error = tokio::task::JoinError;
16    /// The type of a future awaiting another task.
17    pub type NonBlockingFuture<R> = tokio::task::JoinHandle<R>;
18    /// The type of a future awaiting another thread.
19    pub type BlockingFuture<R> = tokio::task::JoinHandle<R>;
20
21    /// Spawns a new task, potentially on the current thread.
22    pub fn spawn<F: Future<Output: Send> + Send + 'static>(
23        future: F,
24    ) -> NonBlockingFuture<F::Output> {
25        tokio::task::spawn(future)
26    }
27
28    /// Spawns a blocking task on a new thread.
29    pub fn spawn_blocking<R: Send + 'static, F: FnOnce() -> R + Send + 'static>(
30        future: F,
31    ) -> BlockingFuture<R> {
32        tokio::task::spawn_blocking(future)
33    }
34}
35
36#[cfg(web)]
37mod implementation {
38    use futures::channel::oneshot;
39
40    use super::*;
41
42    /// The type of errors that can result from awaiting a task to completion.
43    pub type Error = oneshot::Canceled;
44    /// The type of a future awaiting another task.
45    pub type NonblockingFuture<R> = oneshot::Receiver<R>;
46    /// The type of a future awaiting another thread.
47    pub type BlockingFuture<R> = oneshot::Receiver<R>;
48
49    /// Spawns a new task on the current thread.
50    pub fn spawn<F: Future + 'static>(future: F) -> NonblockingFuture<F::Output> {
51        let (send, recv) = oneshot::channel();
52        wasm_bindgen_futures::spawn_local(async {
53            let _ = send.send(future.await);
54        });
55        recv
56    }
57
58    /// Spawns a blocking task on a new Web Worker.
59    pub fn spawn_blocking<R: Send + 'static, F: FnOnce() -> R + Send + 'static>(
60        task: F,
61    ) -> BlockingFuture<R> {
62        let (send, recv) = oneshot::channel();
63        wasm_thread::spawn(move || {
64            let _ = send.send(task());
65        });
66        recv
67    }
68}
69
70pub use implementation::*;