Skip to main content

vortex_io/runtime/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! A Vortex runtime provides an abstract way of scheduling mixed I/O and CPU workloads onto the
5//! various threading models supported by Vortex.
6//!
7//! In the future, it may also include a buffer manager or other shared resources.
8//!
9//! The threading models we currently support are:
10//! * Single-threaded: all work is driven on the current thread. This is also the model to use on
11//!   WebAssembly targets that have no JavaScript event loop.
12//! * Multi-threaded: work is driven on a pool of threads managed by Vortex.
13//! * Worker Pool: work is driven on a pool of threads provided by the caller.
14//! * Tokio: work is driven on a Tokio runtime provided by the caller.
15//! * WebAssembly: work is driven by `wasm_bindgen_futures`.
16//!
17//! Callers may also implement [`Executor`] themselves and install it with
18//! `RuntimeSessionExt::with_handle`.
19
20use futures::future::BoxFuture;
21
22mod abort;
23mod blocking;
24pub use blocking::*;
25mod handle;
26pub use handle::*;
27mod platform;
28pub mod single;
29
30// Runtimes that need threads, and so are unavailable on WebAssembly.
31#[cfg(not(target_arch = "wasm32"))]
32mod blocking_pool;
33#[cfg(not(target_arch = "wasm32"))]
34pub mod current;
35#[cfg(not(target_arch = "wasm32"))]
36mod pool;
37#[cfg(not(target_arch = "wasm32"))]
38mod smol;
39
40#[cfg(feature = "tokio")]
41pub mod tokio;
42// target_os = "unknown" matches browser WebAssembly, excluding WASI targets that do not use this
43// browser-specific runtime. Without `wasm-bindgen` there is no JavaScript event loop to schedule
44// onto, and callers should drive a `single::SingleThreadRuntime` instead.
45#[cfg(all(
46    target_arch = "wasm32",
47    target_os = "unknown",
48    feature = "wasm-bindgen"
49))]
50pub mod wasm;
51
52#[cfg(test)]
53mod tests;
54
55/// Trait used to abstract over different async runtimes.
56pub trait Executor: Send + Sync {
57    /// Spawns a future to be executed on the runtime.
58    ///
59    /// The future should continue to be polled in the background by the runtime.
60    /// The returned `AbortHandle` may be used to optimistically cancel the future.
61    fn spawn(&self, fut: BoxFuture<'static, ()>) -> AbortHandleRef;
62
63    /// Spawns a future doing IO to be executed on the runtime.
64    /// This allows `Executor` implementation to split work between multiple async runtime.
65    /// By default, it just calls `Executor::spawn`.
66    fn spawn_io(&self, fut: BoxFuture<'static, ()>) -> AbortHandleRef {
67        self.spawn(fut)
68    }
69
70    /// Spawns a CPU-bound task for execution on the runtime.
71    ///
72    /// The returned `AbortHandle` may be used to optimistically cancel the task if it has not
73    /// yet started executing.
74    fn spawn_cpu(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef;
75
76    /// Spawns a blocking I/O task for execution on the runtime.
77    ///
78    /// The returned `AbortHandle` may be used to optimistically cancel the task if it has not
79    /// yet started executing.
80    fn spawn_blocking_io(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef;
81}
82
83/// A handle that may be used to optimistically abort a spawned task.
84///
85/// If dropped, the task should continue to completion.
86/// If explicitly aborted, the task should be cancelled if it has not yet started executing.
87pub trait AbortHandle: Send + Sync {
88    fn abort(self: Box<Self>);
89}
90
91pub type AbortHandleRef = Box<dyn AbortHandle>;