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