Repository navigation
bugfix: new connects took the idle connection handed to a queued connect, which then went past the pool size. - #418
Merged
zhuizhuhaomeng merged 2 commits intoNov 5, 2026
Conversation
Hand idle connections and free pool slots directly to queued connect operations. Track waiting and posted operations separately so new connects cannot take a connection assigned to a waiter or exceed the configured pool size. Reuse cached peers before opening a connection when a resumed operation owns an empty slot. Release or transfer each slot once on cancellation, timeout, connection failure, session cleanup, and pool shutdown. Keep queued sockets busy until their connect completes and preserve their pool on rejected concurrent operations. Add regression and stress coverage for handoff, spare capacity, failed connects, coroutine cleanup, and shutdown in preread and content phases.
Account for the compare_expire method registered by lua-resty-core. Update the shared dictionary expectation from 22 to 23 entries. Validation: t/062-count.t passes all 45 assertions with nginx 1.31.8 and lua-resty-core 81c8704.
zhuizhuhaomeng
force-pushed
the
bugfix/backlog-keepalive-queue-jump
branch
from
November 5, 2026 14:41
f8bc411 to
b3aa80c
Compare
zhuizhuhaomeng
approved these changes
Nov 5, 2026
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.
I hereby granted the copyright of the changes in this pull request
to the authors of this stream-lua-nginx-module project.
This is the stream counterpart of openresty/lua-nginx-module#2544. It now follows the design #2544 settled on: the direct handoff from b965a88 there, with the fixes that came after it.
With a connection pool
backlog,setkeepalive()posts the resumption of the next queued operation so that it takes the idle connection. Aconnect()made before that event runs callsngx_stream_lua_get_keepalive_peer()first and takes the connection. The resumed operation then finds no idle connection. Resumed operations skip the backlog check inngx_stream_lua_socket_tcp_connect_helper(), so it opens a new one, and the pool can grow up topool_size + backlog. Since #415 every freed slot posts its own operation, which makes this much more frequent.Final design
A pool keeps two counts:
connectionsis the slots handed out: active sockets, cached idle connections and posted connect operations.waitingis the operations still queued inwait_connect_op, which hold no slot.The backlog check is
waiting >= backlog. Posted operations move to their ownposted_connect_opqueue, which replaces thenext_connect_opcursor.When
setkeepalive()returns a connection while someone waits, the connection does not go tocache. It is attached to the head waiter (op->item, withitem->ownerpointing back), and the waiter takes it withngx_stream_lua_socket_tcp_reuse_peer()when its resumption runs. New connects look atcacheonly, so they cannot take it.Every place that frees a slot goes through
ngx_stream_lua_socket_tcp_release_slot(), whether or not a connection comes with it. If someone waits, it resumes the head waiter with the slot and the connection, if any. Otherwise it puts the connection incache, or decrementsconnectionswhen there is no connection.A connection closed while it waits for its owner only clears the owner's
item; the owner then connects in its slot. An operation resumed with an empty slot first takes the head ofcachewhen it runs, and gives its spare slot back if it gets one.Commits
connect()skipped every idle connection while any operation waited. Replaced by the second commit.reservedqueue, out of reach of new connects. Replaced by d701ffa.waiting.release_slot()without a connection, and test 64 stays.t/068-socket-keepalive.t, and a newt/196-socket-keepalive-queue.t, ported from #2544. Two kinds of http case needed changes:t/196runs its handoff, cancellation and timeout checks in the preread and content phases, and keeps the fixed-seed stress case.Tests
t/196passes, including a run withTEST_NGINX_SOCKET_POOL_ROUNDS=60.t/068with memcached, against this branch and against aa0ba51, the reserved queue. Tests 1 to 64 fail the same way with both, for reasons in my local setup: tests 3 to 9, 11, 12, 25, 33, 45, 53 and 54. On aa0ba51, 13 of the new tests fail: 65 to 69, 71, 72, 75 to 77, 86, 87 and 89.Contributed by AxisNow.