Skip to main content

Crate runite

Crate runite 

Source
Expand description

An event-loop-per-thread async runtime with JavaScript-style scheduling, built for interactive applications.

Each runite runtime thread owns a single-threaded event loop with JavaScript-style microtask/macrotask scheduling, backed by a platform-specific async I/O backend (io_uring on Linux, kqueue on macOS, IOCP on Windows). Tasks on a thread are !Send and never migrate, so most runtime state needs no locking; explicit worker threads provide parallelism and communicate through channels and ThreadHandles.

Unlike Tokio’s default runtime or async-std, there is no work-stealing multithreaded scheduler. Continuations and wakeups are queued as microtasks on the same runtime thread, while timers, I/O callbacks, cross-thread wakes, and queue_macrotask work run as macrotasks after the microtask queue has drained.

§Getting started

The usual entry point is the #[runite::main] attribute, which drives the event loop to completion around your main:

#[runite::main]
async fn main() {
    let contents = runite::fs::read_to_string("Cargo.toml").await.unwrap();
    println!("{} bytes", contents.len());
}

You can also drive the loop yourself. spawn schedules async work and run runs the current thread until everything queued is complete — handy for embedding the runtime or writing tests:

use std::rc::Rc;
use std::cell::Cell;
use std::time::Duration;

let total = Rc::new(Cell::new(0u32));
let result = Rc::clone(&total);

runite::spawn(async move {
    let (tx, mut rx) = runite::channel::mpsc::channel(8);
    runite::spawn(async move {
        for value in 1..=3 {
            runite::time::sleep(Duration::from_millis(1)).await;
            tx.send(value).await.unwrap();
        }
    });
    let mut sum = 0;
    while let Some(value) = rx.recv().await {
        sum += value;
    }
    result.set(sum);
});

runite::run();
assert_eq!(total.get(), 6);

§Where to look next

§Cargo features

  • hyper — integrate runite sockets with the hyper HTTP library.
  • futures-compat — adapters between runite’s I/O traits and the futures-io ecosystem (see the io::compat module, enabled by this feature).

§Platform support

runite currently targets:

  • Linux (io_uring) on x86_64 and aarch64
  • macOS aarch64 (kqueue)
  • Windows (IOCP) on x86_64

Building for any other target raises a compile error. On Windows, sockets, files, and child-process pipes are driven by overlapped I/O through one completion port per runtime thread; runite::fd and runite::net::unix are Unix-only. See docs/WINDOWS.md in the repository for the backend design.

§Minimum Linux kernel

The io_uring backend targets Linux 6.1 or newer (the current LTS line), which is what CI and the maintainers test against. It may run on older kernels subject to the feature notes below, but that is not tested.

Hard requirements (no fallback — the runtime will not function without them):

  • 5.6 — the base ring: openat/read/write/fsync/statx/close and friends, which every file and socket operation builds on.
  • 5.18IORING_OP_MSG_RING, used to wake one runtime thread from another. A single-threaded runtime can run without it, but spawn_worker-based multithreading (and any cross-thread ThreadHandle wake) requires 5.18+.

Soft requirements (a synchronous syscall fallback runs transparently on older kernels, so only native-io_uring performance is affected):

  • File truncation (OpenOptions::truncate, File::set_len) uses IORING_OP_FTRUNCATE (6.9) and falls back to ftruncate(2).
  • The socket lifecycle operations — socket (5.19), bind/listen (6.11), and connect/accept/shutdown/send/recv — fall back to their blocking equivalents when the kernel lacks the opcode.

So the recommended 6.1 LTS floor exercises every feature; the only hard lower bounds are 5.6 (single-threaded) and 5.18 (multithreaded).

Re-exports§

pub use stdio::Stderr;
pub use stdio::Stdin;
pub use stdio::Stdout;
pub use stdio::stderr;
pub use stdio::stdin;
pub use stdio::stdout;
pub use task::BlockingJoinHandle;
pub use task::JoinError;
pub use task::spawn_blocking;

Modules§

channel
Async channels for task and thread communication.
fdUnix
File-descriptor readiness helpers backed by the runtime driver.
fs
Portable async filesystem primitives.
hyper_rthyper
Hyper runtime glue: an executor and a timer backed by runite.
io
Asynchronous I/O traits, adapters, and stream utilities.
net
Portable async networking primitives.
os
OS-specific extensions to runite types, mirroring std::os.
process
Async subprocess management.
signal
Async signal handling.
stdio
Async standard stream helpers.
sync
Single-threaded async synchronization primitives.
task
Task ownership and blocking-offload primitives.
time
Runtime time primitives.

Macros§

join
Awaits multiple futures concurrently on the current task.
select
Resolves with the handler for the first future that becomes ready.
try_join
Awaits multiple Result-returning futures concurrently on the current task.

Structs§

AbortHandleLinux, or Windows, or AArch64 and macOS
Cloneable handle that can abort a queued task without joining it.
IntervalHandleLinux, or Windows, or AArch64 and macOS
Handle returned by time::set_interval.
JoinHandleLinux, or Windows, or AArch64 and macOS
Handle returned by spawn.
ThreadHandleLinux, or Windows, or AArch64 and macOS
A cloneable, Send handle for queueing macrotasks onto a specific runtime thread from any thread.
TimeoutHandleLinux, or Windows, or AArch64 and macOS
Handle returned by time::set_timeout.
WorkerHandleLinux, or Windows, or AArch64 and macOS
A handle to a worker runtime thread spawned with spawn_worker.
YieldNowLinux, or Windows, or AArch64 and macOS
Future returned by yield_now.

Enums§

QueueErrorLinux, or Windows, or AArch64 and macOS
Returned by ThreadHandle::queue_macrotask when the target runtime is shutting down or its cross-thread macrotask queue is full.

Functions§

block_onLinux, or Windows, or AArch64 and macOS
Drives the current thread’s event loop until future completes, then returns its output.
current_thread_handleLinux, or Windows, or AArch64 and macOS
Returns a ThreadHandle to the current runtime thread.
queue_macrotaskLinux, or Windows, or AArch64 and macOS
Queues a one-shot closure to run as a macrotask on the current runtime thread.
queue_microtaskLinux, or Windows, or AArch64 and macOS
Queues a one-shot closure to run as a microtask on the current runtime thread.
runLinux, or Windows, or AArch64 and macOS
Runs the current thread’s event loop until all work is complete.
run_ready_tasksLinux, or Windows, or AArch64 and macOS
Runs only the tasks and microtasks that are ready right now, then returns.
run_until_stalledLinux, or Windows, or AArch64 and macOS
Drives the event loop until it would next block waiting on the I/O driver.
spawnLinux, or Windows, or AArch64 and macOS
Spawns future onto the current runtime thread and returns a JoinHandle.
spawn_workerLinux, or Windows, or AArch64 and macOS
Spawns a new OS thread running its own independent runtime event loop.
yield_nowLinux, or Windows, or AArch64 and macOS
Returns a future that yields back to the runtime scheduler once.

Attribute Macros§

main
Marks fn main as the runite entry point.
test
Marks an async fn as a runite-driven test.