Skip to main content

Config

Struct Config 

Source
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: usize

Loop threads; 0 means one per CPU this process may use.

§pin_threads: bool

Pin 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: DriverConfig

I/O driver settings, including the back end.

§buffer_classes: [usize; 3]

Buffer class sizes; the smallest is also the receive buffer size.

§pool_cache: usize

Most buffers each loop keeps cached in its smallest class.

§recv_buffers: usize

Receive buffers each loop keeps lent to its driver (io_uring: in the provided-buffer ring).

§max_input: usize

Most unconsumed input bytes per connection; beyond it the connection is closed.

§max_connections: usize

Most connections in total; more are accepted and closed at once.

§max_connections_per_loop: usize

Most connections per loop.

§write_high_water: usize

Above this many queued output bytes a connection stops reading.

§write_low_water: usize

At or below this many queued output bytes reading resumes.

§timer_tick: Duration

Timer resolution.

§offload: OffloadConfig

The shared offload pool.

§listen: ListenOptions

Listener 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: String

Loop thread name prefix.

§lazy_loops: bool

Start 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: Duration

Lingering 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: usize

The most input a lingering close reads and drops before it closes anyway. Default 256 KiB.

§reserve_fds: usize

Linux: 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: bool

With 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.

Trait Implementations§

Source§

impl Clone for Config

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Config

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Forget for Config

§

impl Freeze for Config

§

impl Move for Config

§

impl RefUnwindSafe for Config

§

impl Send for Config

§

impl Sync for Config

§

impl Unpin for Config

§

impl UnsafeUnpin for Config

§

impl UnwindSafe for Config

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.