pub struct Config {Show 22 fields
pub threads: usize,
pub pin_threads: bool,
pub cpus: Option<Vec<usize>>,
pub driver: DriverConfig,
pub buffer_classes: [usize; 3],
pub pool_cache: usize,
pub recv_buffers: usize,
pub max_input: usize,
pub max_connections: usize,
pub max_connections_per_loop: usize,
pub write_high_water: usize,
pub write_low_water: usize,
pub timer_tick: Duration,
pub offload: OffloadConfig,
pub listen: ListenOptions,
pub thread_name: String,
pub lazy_loops: bool,
pub linger: Duration,
pub linger_bytes: usize,
pub reserve_fds: usize,
pub stack_size: Option<usize>,
pub leave_cpu_for_network: bool,
}Expand description
Runtime settings. Config::default() suits a server.
Fields§
§threads: usizeLoop threads; 0 means one per CPU this process may use.
pin_threads: boolPin loop i to CPU cpus[i % cpus.len()] (Linux and Windows).
cpus: Option<Vec<usize>>The CPUs to pin to; None means the process affinity set.
driver: DriverConfigI/O driver settings, including the back end.
buffer_classes: [usize; 3]Buffer class sizes; the smallest is also the receive buffer size.
pool_cache: usizeMost buffers each loop keeps cached in its smallest class.
recv_buffers: usizeReceive buffers each loop keeps lent to its driver (io_uring: in the provided-buffer ring).
max_input: usizeMost unconsumed input bytes per connection; beyond it the connection is closed.
max_connections: usizeMost connections in total; more are accepted and closed at once.
max_connections_per_loop: usizeMost connections per loop.
write_high_water: usizeAbove this many queued output bytes a connection stops reading.
write_low_water: usizeAt or below this many queued output bytes reading resumes.
timer_tick: DurationTimer resolution.
offload: OffloadConfigThe shared offload pool.
listen: ListenOptionsListener options (backlog, buffer sizes; reuse_port is set by the runtime). The
default backlog is the system maximum, and defer_accept is Some(1): on Linux a
connection is handed over once its first bytes arrived, so the first request is read
in the same turn as the accept. Set defer_accept to None for a protocol where the
server speaks first.
thread_name: StringLoop thread name prefix.
lazy_loops: boolStart only loop 0 at Builder::start, without waiting for it (the listeners are bound
first, so connections wait in the backlog), and the other loops in the background when
loop 0 holds three connections at once. A server that is idle, or serves one connection
at a time (a FaaS instance), then pays for one loop thread in start-up time and memory
instead of one per core. Connections accepted while the other loops start (well under a
millisecond) are held, then spread over every loop, and loop 0 hands out its accepts for
a second after. A loop that fails to build its driver is logged on standard error
instead of failing start (binding errors still fail it). Ignored when the runtime has
UDP sockets (Builder::udp): every loop starts at once then, since a socket added
later to a SO_REUSEPORT group would take over some established QUIC connections.
Default false here (a load generator wants every loop at once); the simoom server
turns it on.
linger: DurationLingering close: after a graceful close (crate::Ctx::close) the write side is shut
down and input is read and dropped until the peer closes, for at most this long, before
the socket is closed (closing over unread input resets the connection, and a reset can
destroy the last response at the peer). Duration::ZERO closes at once. Default 2 s.
linger_bytes: usizeThe most input a lingering close reads and drops before it closes anyway. Default 256 KiB.
reserve_fds: usizeLinux: descriptor table slots reserved at start, before the loop threads exist (capped
at the soft RLIMIT_NOFILE). Growing the table once threads run stalls the thread that
crosses each step (64, 128, 256…) for an RCU grace period, 10-30 ms on a VM. 0 skips
it. Default 1024 (8 KiB of kernel memory).
stack_size: Option<usize>Stack size of the loop threads; None keeps std’s default (2 MiB, or RUST_MIN_STACK).
Only touched pages cost memory, so this mostly matters for address space.
leave_cpu_for_network: boolWith the default loop count (threads 0, no cpus) on 4 CPUs or more: one loop fewer
than CPUs when the network’s receive processing concentrates on one CPU (a NIC with a
single receive queue and no RPS, simoom_sys::cpu::net_rx_concentrated), and the loop
threads keep off that CPU. It spends most of its time in softirq at high packet rates, and
a loop sharing it falls behind the others with every connection it holds (K12: S1 at 256
connections on a 4-vCPU droplet, 111k req/s with four loops against 151k with three).
Leaving the CPU free is not enough: the scheduler moves a loop thread woken by that CPU’s
softirq onto it, so unrestricted loops ran there 40% of the time. Default true.