pub fn spawn_reader<A: Application, R: AsRawFd + Send + 'static>(
producer: Producer<InputSlot<A::Event>>,
decoder: RequestDecoderArc<A>,
halt: HaltGate,
refusals: RefusalSender<A::Report>,
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>>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).
While halt refuses writes, the reader answers them through
refusals instead of publishing them — see crate::halt.
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.