From 1b1ea124c8e663fac9b74d47afb664863d2ba565 Mon Sep 17 00:00:00 2001 From: "Claude (sandbox)" Date: Mon, 10 Aug 2026 05:47:22 +0000 Subject: [PATCH] feat(serve): plumb Config.max_actors through to smarm init Config gained a max_actors: Option (None = smarm's DEFAULT_MAX_ACTORS of 16_384). serve_with now applies it to the smarm runtime config, so the per-connection actor slab can be sized to the deployment's peak concurrent connections. Since each connection is one actor, the slab was the hard cap on concurrent connections (previously an un-raisable 16_384) regardless of RAM/fds; slots are ~256 B so raising it is cheap next to per-conn stacks. Verified on the GPU box: default caps at 16_383 held connections; with max_actors raised, a paced ramp holds 100_000 concurrent slow-header connections at 12.4 KB RSS / 2 VMAs each (1.29 GB total) on one pinned core. --- src/serve.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/serve.rs b/src/serve.rs index e6c0d25..2124ad2 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -65,6 +65,12 @@ pub struct Config { /// Default: 256 KiB. The reserve is virtual/demand-paged, so raising it /// costs address space, not RSS, until a handler actually uses it. pub conn_stack_reserve: usize, + /// Maximum concurrently-live actors — smarm's fixed slot slab, allocated + /// once at init. Each connection is one actor, so this is also the hard + /// cap on concurrent connections. `None` uses smarm's default (16_384). + /// Slots are ~256 B, so raising this is cheap relative to per-connection + /// stacks; size it to peak concurrent connections. + pub max_actors: Option, } /// Default per-connection actor stack reserve (see [`Config::conn_stack_reserve`]). @@ -90,6 +96,7 @@ impl Config { max_message_bytes: 4 * 1024 * 1024, scheduler_threads: None, conn_stack_reserve: DEFAULT_CONN_STACK_RESERVE, + max_actors: None, } } @@ -326,10 +333,13 @@ pub fn serve_with_shutdown( let conn_stack_reserve = config.conn_stack_reserve; let drain_timeout = config.drain_timeout; - let smarm_cfg = match config.scheduler_threads { + let mut smarm_cfg = match config.scheduler_threads { Some(n) => smarm::Config::exact(n), None => smarm::Config::default(), }; + if let Some(m) = config.max_actors { + smarm_cfg = smarm_cfg.max_actors(m); + } let rt = smarm::init(smarm_cfg); // Listener self-termination flag — see the shutdown sequence below. let shutdown_flag = Arc::new(AtomicBool::new(false));