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