Skip to main content

Module async_ring

Module async_ring 

Source
Expand description

AsyncSpscRing: Future-shaped async adapter on top of crate::blocking_spsc_ring::BlockingSpscRing.

Turns the synchronous send_blocking / recv_blocking API into send(...).await / recv(...).await so SubEtha rings compose with any async executor (tokio, smol, async-std, custom). The adapter is executor-agnostic: it uses only std::future::Future plus std::thread to bridge the cross-process kernel-park to the Rust Waker ecosystem.

§How the bridge works

Rust’s async model is “Future returns Pending and registers a Waker; something fires the Waker; executor re-polls.” The underlying CrossProcessWaker is a kernel-park primitive that does the wait OFF the async runtime’s thread. To bridge:

  1. First poll calls try_* on the inner ring. If immediately ready, return Poll::Ready.
  2. Otherwise, spawn a std::thread that calls the blocking counterpart (recv_blocking / send_blocking) with the caller-supplied timeout. Park the rust Waker.
  3. When the blocking call returns, store the result + fire the Waker.
  4. Next poll observes the stored result and returns Poll::Ready.

§Why a bounded timeout is required

Dropping a pending AsyncRecv / AsyncSend future does NOT cancel the spawned worker thread (std::thread lacks safe cancellation). The thread’s worst-case lifetime equals the caller-supplied timeout. Unbounded waits are rejected at the type level by requiring Duration (not Option<Duration>).

§Worker-thread cost model

Each in-flight future spawns one OS thread. This pattern fits the substrate’s intended use of async (a small number of long-running consumer tasks per process, not thousands of short-lived futures). Callers driving high concurrency batch through one BlockingSpscRing per consumer task and call recv_blocking directly inside tokio::task::spawn_blocking (or the executor’s equivalent).

Structs§

AsyncRecv
Future returned by AsyncSpscRing::recv.
AsyncSend
Future returned by AsyncSpscRing::send.
AsyncSpscRing
Wrapper providing .recv(timeout).await and .send(timeout).await.