Conversation
Cap the number of concurrent connections served across all listeners with a new `max_connections` config key (default `infinity`, so the existing behaviour is unchanged). The acceptor claims a slot from a shared atomics counter right after accept, before the worker is spawned, and the worker releases it from a try/after so an abnormal exit still gives the slot back and the count cannot drift upwards. Over the limit the accepted socket is closed immediately without a response: a send from the accept loop would stall every pending accept behind one slow client. Rejections emit `[whitecap, connections, max_connections]`, and `whitecap:connections/0` returns the current count. `infinity` short-circuits in both the acceptor and the connection worker, so the default configuration does no counter work on the hot path.
counters has no add-and-get, so the check read the counter back after incrementing it and two acceptors could each see a value under the limit for the same slot. atomics:add_get/3 returns the post-increment value in one atomic op, making the limit exact and dropping an op from the accept path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Caps concurrent connections served across all listeners with a new
max_connectionsconfig key. Default isinfinity, so existing behaviour is unchanged.accept, before the worker is spawned; the worker releases it from atry/after, so an abnormal exit still gives the slot back and the count cannot drift upwards.[whitecap, connections, max_connections];[whitecap, connections, accept]now fires only for connections handed to a worker.whitecap:connections/0returns the current count.infinityshort-circuits in both the acceptor and the connection worker, so the default configuration does no counter work on the hot path.The limit is VM-wide rather than per-listener, matching how
max_keepaliveand the timeouts are already configured.Test plan
New
test/whitecap_max_connections_tests.erlcovers the N+1th connection being closed unanswered, a closed connection freeing its slot, and a crashing handler's worker freeing its slot.compile(warnings-as-errors),xref,eunit(35 tests) anddialyzerpass locally.CHANGELOG and app vsn are left for the release commit.