Skip to content

fix(pool): bound release ping to prevent permit leaks - #4363

Open
noxiouz wants to merge 1 commit into
transact-rs:mainfrom
noxiouz:ping_timeout
Open

fix(pool): bound release ping to prevent permit leaks#4363
noxiouz wants to merge 1 commit into
transact-rs:mainfrom
noxiouz:ping_timeout

Conversation

@noxiouz

@noxiouz noxiouz commented Aug 4, 2026

Copy link
Copy Markdown

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 DecrementSizeGuard restores 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.

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
noxiouz marked this pull request as ready for review August 4, 2026 17:51
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.

Dropping a PoolConnection whose connection is silently dead leaks the pool permit forever (return_to_pool cleanup never completes)

1 participant