fix(pool): bound release ping to prevent permit leaks - #4363
Open
noxiouz wants to merge 1 commit into
Open
Conversation
PoolConnection::drop() pings a connection before returning it to the idle queue. If the TCP peer is silently unresponsive, that ping can wait forever while retaining the pool's semaphore permit. Once all permits are stranded, subsequent connection acquisitions time out and the pool cannot recover. Bound the release-side ping with a five-second runtime-neutral timeout. Successful pings still return connections to the pool, while driver errors retain the existing hard-close behavior. On timeout, synchronously drop the floating connection without further socket I/O so DecrementSizeGuard restores the pool size and semaphore permit even if flushing or shutdown could block. Add a fake PostgreSQL server regression test that completes startup but never answers the release ping, then verifies that the pool opens a replacement. Fixes transact-rs#4349
noxiouz
marked this pull request as ready for review
August 4, 2026 17:51
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.
PoolConnection::drop()spawns a task that pings the connection before returning it to the idle queue. When a TCP peer becomes silently unresponsive, that ping can wait forever while retaining the pool semaphore permit. Once every permit is stranded, subsequent acquisitions time out and the pool cannot recover.Fixes #4349.
The release ping now uses the runtime-neutral timeout helper. Successful pings still return the connection to the idle queue, and completed driver errors retain the existing hard-close behavior. If the timeout elapses, the floating connection is dropped synchronously so
DecrementSizeGuardrestores pool size and capacity without entering another potentially blocked flush or shutdown.The regression test uses an in-process Tokio PostgreSQL server that completes startup, reads client traffic, and never answers the release ping. It verifies that dropping the stalled connection frees capacity and allows a replacement connection to open.