Skip to main content

spawn_reader

Function spawn_reader 

Source
pub fn spawn_reader<A: Application, R: AsRawFd + Send + 'static>(
    producer: Producer<InputSlot<A::Event>>,
    decoder: RequestDecoderArc<A>,
    halt: HaltGate,
    early_replies: EarlyReplySender<A::Report>,
    metrics: Arc<IngressMetrics>,
    ack_policy: BootedClaim,
    control_tx: Sender<ControlEvent>,
    core: usize,
    connection_timeout: Option<Duration>,
    tick_cadence: Option<Duration>,
    sizing: RingSizing,
    shutdown: Arc<AtomicBool>,
) -> Result<UringReaderHandle<R>>
where A::Event: Send + Sync + 'static, A::Report: Send + 'static,
Expand description

Spawn the io_uring reader thread. Returns a handle for registering connections.

One reader thread serves every TCP connection on the server. io_uring with multishot RECV multiplexes thousands of sockets efficiently and the matching stage is the throughput limit, so adding more reader threads would not raise throughput — it would only re-introduce contention on the input ring’s multi-producer cursor.

tick_cadence: Some(d) makes the reader the clock-tick generator: it arms an IORING_OP_TIMEOUT so submit_and_wait returns at the tick deadline even when no client traffic is flowing, then publishes a JournalEvent::Tick { now_ns } onto the same input ring it uses for client requests. Pass None to disable the tick (useful for benchmarks that don’t exercise time-driven features).

Every request it does not publish — one the application’s decoder filters or refuses, a write refused while halt refuses writes, one shed on a full input ring — the reader answers through early_replies — see crate::halt. It counts those it sheds, filters and refuses into metrics, with the connections it parks, for the health endpoint.

The reader also journals the admin ACK-POLICY command’s requests: it attaches ack_policy with its wakeup eventfd, so a request posted while it is parked brings it back round its loop, which publishes the entry (see crate::policy_control).

sizing sets the ring’s depth and the provided-buffer pool (see RingSizing). Returns once the reader holds its io_uring instance and buffer pool, or with the error that kept it from getting them — a startup error, not a dead thread: the kernel charges ring memory against the locked-memory limit, and running out of it is an operator-fixable condition the node has to report.