Manifold
A Manifold is the long-lived, per-core state machine the runtime drives with
completions straight from io_uring (or kqueue in dev) — the runtime is named after
it. It’s mounted once and lives for the whole executor: instead of spawning machinery
per request, you put durable per-core work — a listener, a database connection, a
timer — in a manifold and let the executor feed it kernel events until the program
exits.
core executor mount exit
task / request
dope · mounted once
Listener
Connector (db)
Timer
The trait
Section titled “The trait”pub trait Manifold: Sized { const ID: u8 = 0; fn dispatch( self: Pin<&mut Self>, ev: backend::Event, driver: &mut Driver, ); fn idle(self: Pin<&Self>) -> Idle { Idle::Park(None) } // pre_park, on_wake, on_shutdown …}- Completions go straight from the kernel to the manifold — no queue between threads.
const IDroutes through a generatedmatch, not a vtable — the no-dyn feature in practice.Pin<&mut Self>— manifolds are in-place machines, not values shuffled around.
Composing on a core
Section titled “Composing on a core”Several manifolds compose through #[derive(Dispatcher)]:
#[derive(Dispatcher)]struct App { #[manifold] http: Listener</* … */>, #[manifold] db: Connector</* … */>,}Each field is a concrete type; the derive generates dispatch and wake as match arms
over the IDs. dope ships the common ones — listener, connector — so
cartel and sark build straight on them.
For ordinary async / await, reach for the Fiber.