Skip to content

feat: daemon accept loop honours --max-connections admission cap#4042

Merged
oferchen merged 1 commit into
masterfrom
feat/daemon-max-connections-admission-2157
May 14, 2026
Merged

feat: daemon accept loop honours --max-connections admission cap#4042
oferchen merged 1 commit into
masterfrom
feat/daemon-max-connections-admission-2157

Conversation

@oferchen
Copy link
Copy Markdown
Owner

Summary

  • Wire ConnectionCounter::active() into the daemon accept loop so a configurable concurrent-connection ceiling is actually enforced; the helper previously carried #[allow(dead_code)] and was never consulted.
  • Add --max-connections N to the daemon CLI parser, with duplicate detection mirroring --max-sessions.
  • When the cap is reached, the next accepted socket is refused with @ERROR: max connections (N) reached -- try again later\n (matching upstream clientserver.c:744-756 byte for byte), the socket is dropped, no worker thread is spawned, and the accept loop continues serving future connections.
  • Refusal applies in both the single-listener and the dual-stack accept paths.
  • Without --max-connections the daemon behaves exactly as before.

This implements task D1 from the daemon-scalability audit added in #4023 (docs/audits/daemon-thread-per-connection-1673.md). Under high concurrency (10k+ conns) the daemon previously panicked with clone3: EAGAIN; with this change it gracefully refuses excess clients instead.

Test plan

  • cargo fmt --all
  • New unit tests in crates/daemon/src/daemon/sections/server_runtime/tests.rs:
    • accept_loop_refuses_when_at_capacity - two guards held, third connect receives the exact upstream wording and the counter is left at 2.
    • accept_loop_recovers_after_disconnect - same setup, dropping one guard re-admits the next connect.
    • refuse_if_at_capacity_admits_when_no_cap_configured - guard count is irrelevant when the cap is unset.
  • New CLI parsing tests in crates/daemon/src/daemon/runtime_options/tests.rs cover the option, zero/non-numeric rejection, and duplicate detection.
  • Existing daemon nextest suite remains green (no behaviour change when --max-connections is unset).

Wire `ConnectionCounter::active()` (previously `#[allow(dead_code)]`)
into the accept loop. When `--max-connections N` is set and N
worker guards are live, the next accepted socket is refused with
`@ERROR: max connections (N) reached -- try again later\n` and
dropped without spawning a thread, while the accept loop continues.

upstream: clientserver.c:744-756 - `claim_connection()` emits the
same wording for per-module caps via `io_printf(f_out, ...)`.

Closes the daemon-scalability admission gap surfaced by the
thread-per-connection audit at
`docs/audits/daemon-thread-per-connection-1673.md`.
@github-actions github-actions Bot added the enhancement New feature or request label May 14, 2026
@oferchen oferchen merged commit a6a0775 into master May 14, 2026
38 of 39 checks passed
@oferchen oferchen deleted the feat/daemon-max-connections-admission-2157 branch May 14, 2026 14:57
oferchen added a commit that referenced this pull request May 18, 2026
Wire `ConnectionCounter::active()` (previously `#[allow(dead_code)]`)
into the accept loop. When `--max-connections N` is set and N
worker guards are live, the next accepted socket is refused with
`@ERROR: max connections (N) reached -- try again later\n` and
dropped without spawning a thread, while the accept loop continues.

upstream: clientserver.c:744-756 - `claim_connection()` emits the
same wording for per-module caps via `io_printf(f_out, ...)`.

Closes the daemon-scalability admission gap surfaced by the
thread-per-connection audit at
`docs/audits/daemon-thread-per-connection-1673.md`.
oferchen added a commit that referenced this pull request May 18, 2026
Wire `ConnectionCounter::active()` (previously `#[allow(dead_code)]`)
into the accept loop. When `--max-connections N` is set and N
worker guards are live, the next accepted socket is refused with
`@ERROR: max connections (N) reached -- try again later\n` and
dropped without spawning a thread, while the accept loop continues.

upstream: clientserver.c:744-756 - `claim_connection()` emits the
same wording for per-module caps via `io_printf(f_out, ...)`.

Closes the daemon-scalability admission gap surfaced by the
thread-per-connection audit at
`docs/audits/daemon-thread-per-connection-1673.md`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant