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.
11//! * Multi-threaded: work is driven on a pool of threads managed by Vortex.
12//! * Worker Pool: work is driven on a pool of threads provided by the caller.
13//! * Tokio: work is driven on a Tokio runtime provided by the caller.
14//!
15
16use futures::future::BoxFuture;
17use futures::stream::BoxStream;
18
19use crate::file::IoRequest;
20use crate::file::ReadSourceRef;
21
22mod blocking;
23pub use blocking::*;
24mod handle;
25pub use handle::*;
26
27#[cfg(not(target_arch = "wasm32"))]
28pub mod current;
29#[cfg(not(target_arch = "wasm32"))]
30mod pool;
31#[cfg(not(target_arch = "wasm32"))]
32pub mod single;
33#[cfg(not(target_arch = "wasm32"))]
34mod smol;
35#[cfg(feature = "tokio")]
36pub mod tokio;
37#[cfg(target_arch = "wasm32")]
38pub mod wasm;
39
40#[cfg(test)]
41mod tests;
42
43/// Trait used to abstract over different async runtimes.
44pub(crate) trait Executor: Send + Sync {
45    /// Spawns a future to be executed on the runtime.
46    ///
47    /// The future should continue to be polled in the background by the runtime.
48    /// The returned `AbortHandle` may be used to optimistically cancel the future.
49    fn spawn(&self, fut: BoxFuture<'static, ()>) -> AbortHandleRef;
50
51    /// Spawns a CPU-bound task for execution on the runtime.
52    ///
53    /// The returned `AbortHandle` may be used to optimistically cancel the task if it has not
54    /// yet started executing.
55    fn spawn_cpu(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef;
56
57    /// Spawns a blocking I/O task for execution on the runtime.
58    ///
59    /// The returned `AbortHandle` may be used to optimistically cancel the task if it has not
60    /// yet started executing.
61    fn spawn_blocking(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef;
62
63    /// Spawns an I/O task for execution on the runtime.
64    /// The runtime can choose to invoke the task's `Send` or `!Send` versions.
65    ///
66    /// Cancellation is implied by termination of the request stream.
67    fn spawn_io(&self, task: IoTask);
68}
69
70/// A handle that may be used to optimistically abort a spawned task.
71///
72/// If dropped, the task should continue to completion.
73/// If explicitly aborted, the task should be cancelled if it has not yet started executing.
74pub(crate) trait AbortHandle: Send + Sync {
75    fn abort(self: Box<Self>);
76}
77
78pub(crate) type AbortHandleRef = Box<dyn AbortHandle>;
79
80/// A task for driving I/O requests against a source.
81///
82/// Instead of just spawning a future to process requests, we allow each runtime to decide how
83/// spawn the driver for the request stream. This allows runtimes to shared, parallelize, further
84/// spawn, or otherwise manage the I/O task as they see fit.
85///
86// NOTE(ngates): We could in theory make IoSource support as_any if we wanted each runtime to implement the
87// actual read logic themselves? Not sure yet...
88pub(crate) struct IoTask {
89    pub(crate) source: ReadSourceRef,
90    pub(crate) stream: BoxStream<'static, IoRequest>,
91}
92
93impl IoTask {
94    pub(crate) fn new(source: ReadSourceRef, stream: BoxStream<'static, IoRequest>) -> Self {
95        IoTask { source, stream }
96    }
97}