nuclei/lib.rs
1//! # Nuclei
2//!
3//! A proactive async runtime: thread-per-core shards that run tasks and
4//! drive their own IO, timers and buffers. Every operation is completed for
5//! the task that asked for it; no task waits for readiness and then makes
6//! the call itself. IO runs on io_uring on Linux where the kernel allows it,
7//! else on epoll; on kqueue on macOS and the BSDs; and on I/O completion
8//! ports on Windows.
9//!
10//! [`spawn`], [`block_on`] and the rest place work on the process default
11//! [`Runtime`], which starts on first use with no configuration; a
12//! [`Builder`] sets every setting for a runtime of one's own.
13//!
14//! # What is where
15//!
16//! - [`runtime`]: runtimes, their builder and handles, `block_on`, tasks
17//! placed on a worker one names
18//! ([`RuntimeHandle::spawn_on_worker`], [`RuntimeHandle::on_each_worker`])
19//! and values kept per worker ([`shard_local!`]).
20//! - [`task`]: spawning, [`JoinSet`](task::JoinSet), abort handles, ids and
21//! names, task-local values and yielding.
22//! - [`net`]: TCP, UDP and Unix sockets, names, socket options and builders,
23//! stream halves, `shut` and `abort`, and pipes.
24//! - [`io`]: [`Handle`], async operations on std's own IO objects, and the
25//! helpers every stream gets: reads and writes as futures, copies,
26//! buffers, in-memory pipes, the standard streams and readiness; and the
27//! buffers the owned calls lend the driver ([`io::IoBuf`],
28//! [`io::AlignedBuf`], [`io::IoVecBuf`]).
29//! - [`fs`]: files, whole-file calls, metadata and directories; IO at an
30//! offset, direct IO, syncs, the space calls and advisory locks.
31//! - [`time`]: sleeps on a millisecond wheel or to the microsecond,
32//! timeouts, intervals and a clock tests can pause.
33//! - [`sync`]: locks, semaphores, notifications, once-cells, channels and
34//! cancellation tokens, for any executor; [`sync::local`], their cheaper
35//! twins for the tasks of one shard; and [`sync::mesh`], channels between
36//! every pair of a set of parties.
37//! - [`process`] and [`signal`]: child processes, signals and console events.
38//! - [`stats()`]: a snapshot of what every shard is doing, with poll times
39//! when recorded and, with the `io-stats` feature, its IO counts and
40//! latencies.
41//! - [`select!`], [`join!`] and [`try_join!`] wait on several futures in one
42//! task; `#[nuclei::main]`, `#[nuclei::test]` and `#[nuclei::bench]` run
43//! an async function in the runtime.
44//!
45//! A call that needs the default runtime or the calling thread's shard
46//! panics if that cannot start (the system refused its poller: no
47//! descriptors or memory left); [`Builder::build`] and [`task::Builder`]
48//! answer the error instead. [`Builder::build`] also checks every setting
49//! first, and answers one out of range as `InvalidInput` naming it.
50//!
51//! The guide, a path from the first program to production with an example
52//! that runs for every idea, is at <https://nuclei.rs/learn/>.
53//!
54//! ```no_run
55//! use nuclei::net::TcpListener;
56//!
57//! #[nuclei::main]
58//! async fn main() -> std::io::Result<()> {
59//! let listener = TcpListener::bind("127.0.0.1:7000").await?;
60//! loop {
61//! let (stream, _) = listener.accept().await?;
62//! nuclei::spawn(async move {
63//! let mut buf = [0u8; 1024];
64//! while let Ok(n @ 1..) = stream.recv(&mut buf).await {
65//! if stream.send(&buf[..n]).await.is_err() {
66//! break;
67//! }
68//! }
69//! })
70//! .detach();
71//! }
72//! }
73//! ```
74
75// A model-checking build (`--cfg loom`) compiles the loom models and leaves
76// the ordinary tests out, so the helpers only those tests use go unused.
77#![cfg_attr(all(loom, test), allow(dead_code, unused_imports))]
78// No unwrap, expect or panic outside a documented contract, each marked
79// where it is; every unsafe block names what it rests on. Tests and the
80// model-checking build may assert.
81#![cfg_attr(
82 not(test),
83 warn(
84 clippy::unwrap_used,
85 clippy::expect_used,
86 clippy::panic,
87 clippy::unreachable,
88 clippy::todo,
89 clippy::unimplemented,
90 clippy::undocumented_unsafe_blocks
91 )
92)]
93
94mod buf;
95mod compat;
96/// The proactor's configuration: the io_uring settings of every shard and the default backend.
97pub mod config;
98pub mod fs;
99pub mod io;
100mod mem;
101pub mod net;
102mod proactor;
103/// Child processes: spawn one, wait for its exit and talk to it through async pipes.
104pub mod process;
105mod rt;
106/// nuclei's own runtime: shards, tasks, `block_on`, `spawn` and the blocking pool.
107pub mod runtime;
108mod shard_local;
109/// Signals (unix) and console control events (Windows), as streams.
110pub mod signal;
111pub mod stats;
112/// Runtime-independent synchronization primitives: futures and wakers only, usable from any executor.
113pub mod sync;
114#[cfg(any(target_os = "linux", target_os = "android", windows))]
115mod syscore {
116 // The io_uring ring and its probe. Parts of the ring layer (provided
117 // buffer rings, multishot entries, flags) are for the driver's next
118 // steps; their own tests run them now.
119 #[cfg(any(target_os = "linux", target_os = "android"))]
120 #[allow(dead_code)]
121 pub(crate) mod linux;
122 // The kernel32, ws2_32 and ntdll interface of the IOCP driver.
123 #[cfg(windows)]
124 pub(crate) mod windows;
125}
126#[cfg(test)]
127mod alone;
128mod coop;
129mod join_set;
130#[doc(hidden)]
131pub mod macros;
132/// Tasks: spawning, their handles and ids, cancellation from anywhere, and yielding.
133pub mod task;
134mod task_local;
135/// Time: sleeping, timeouts and intervals on the shard's timer wheel.
136pub mod time;
137
138#[cfg(not(any(
139 target_os = "linux", // epoll, iouring
140 target_os = "android", // epoll
141 target_os = "illumos", // epoll
142 target_os = "macos", // kqueue
143 target_os = "ios", // kqueue
144 target_os = "freebsd", // kqueue
145 target_os = "netbsd", // kqueue
146 target_os = "openbsd", // kqueue
147 target_os = "dragonfly", // kqueue
148 windows, // I/O completion ports
149)))]
150compile_error!("Target OS is not supported");
151
152pub use compat::{
153 GlobalExecutorConfig, init, init_with_config, spawn_more_threads, stop_current_thread,
154 stop_thread,
155};
156pub use io::{Handle, IoObject};
157pub use net::TcpStreamGenerator;
158#[cfg(feature = "attributes")]
159pub use nuclei_macros::{bench, main, test};
160pub use proactor::{IoBackend, Proactor, drive};
161pub use runtime::{
162 Builder, FallibleTask, Runtime, RuntimeHandle, Task, block_on, spawn, spawn_blocking,
163 spawn_local,
164};
165pub use stats::stats;
166pub use time::{sleep, timeout};