Skip to content

perf(client): make pool waiter cleanup amortized O(1) on Checkout drop - #345

Open
Nacl-HCl wants to merge 1 commit into
hyperium:masterfrom
Nacl-HCl:fix-pool-waiter-cleanup-4245
Open

Nacl-HCl wants to merge 1 commit into
hyperium:masterfrom
Nacl-HCl:fix-pool-waiter-cleanup-4245

Conversation

@Nacl-HCl

@Nacl-HCl Nacl-HCl commented Nov 2, 2026 •

Copy link
Copy Markdown

Problem

Fixes hyperium/hyper#4245

In the legacy client connection pool, every dropped Checkout with a parked waiter triggers clean_waiters, which runs VecDeque::retain over the entire waiter queue for that key while holding the pool lock. With n parked waiters this is O(n^2) total work — the reporter measured 10.5s for 131,072 concurrent requests against a cold pool.

Fix

put already skips canceled waiters lazily (tx.is_canceled() + pop_front), so the eager full scan on drop is redundant. clean_waiters now only pops the canceled prefix of the queue: each parked sender is popped at most once, making cleanup amortized O(1) per drop. The key entry is still removed once the queue is empty, so the observable cleanup contract is unchanged (test_pool_checkout_drop_cleans_up_waiters passes unmodified).

Verification

  • cargo test --all-features --lib: 107 passed, 0 failed (includes 2 new regression tests: bulk drop cleanup, and out-of-order drop followed by put still waking the live waiter).
  • cargo fmt --all --check: clean.
  • Timing harness (park 20k checkouts, drop all): 15.67s before → 22.6ms after.
  • The description, docs, and comments (words meant for humans) are written by a human, not by an LLM.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hyper-util legacy client: each dropped pool Checkout scans every parked waiter under the pool lock, O(n²) at cold start

1 participant