Skip to content

Fix deadlock in pgxpool under concurrent context cancellation - #2

Open
zhuyh1606-oss wants to merge 1 commit into
jaasielitaigq:mainfrom
zhuyh1606-oss:main
Open

Fix deadlock in pgxpool under concurrent context cancellation#2
zhuyh1606-oss wants to merge 1 commit into
jaasielitaigq:mainfrom
zhuyh1606-oss:main

Conversation

@zhuyh1606-oss

Copy link
Copy Markdown

/claim #1

Problem

Under high-concurrency with rapid context cancellation, pgxpool can deadlock/livelock when:

  1. Multiple goroutines call Acquire with contexts that get cancelled mid-flight
  2. puddle's semaphore token is consumed but resource init fails due to cancel
  3. The constructor goroutine holds the semaphore token until completion
  4. pgxpool retry loop doesn't check ctx between iterations

Fix

Two-part fix:

puddle/pool.go acquire()

Added ctx.Done() check after semaphore acquire succeeds but before resource creation. If the context was cancelled between TryAcquire and the check, the semaphore is released immediately instead of starting a doomed constructor goroutine.

pgxpool/pool.go Acquire()

Added ctx.Err() check in the retry loop after Destroy() calls for expired/unhealthy connections. This terminates the retry loop immediately when context is cancelled, instead of cycling through all maxConns+1 attempts.

Testing

Added TestPoolAcquireStressCancelContention - runs 50 goroutines each acquiring with tight context cancellation (5ms timeout), exercising the semaphore contention + cancel path.

Fixes concurrent context cancellation + semaphore contention causing
pool to livelock. Two-part fix:

1. puddle/pool.go acquire(): check ctx.Done() after semaphore acquire
   to prevent goroutine leak when context is canceled between
   TryAcquire success and resource creation.

2. pgxpool/pool.go Acquire(): check ctx.Err() between retry iterations
   so a cancelled context terminates the retry loop immediately
   instead of cycling through all maxConns attempts.

Includes regression test TestPoolAcquireStressCancelContention that
exercises high-concurrency acquire with rapid context cancellation.
@opirebot

opirebot Bot commented Jul 24, 2026

Copy link
Copy Markdown

😅 Unfortunately there are no rewards left to claim in this issue!

@zhuyh1606-oss

Copy link
Copy Markdown
Author

Hi @jaasielitaigq, any chance to review this PR? The fix addresses the deadlock in pgxpool under context cancellation with a regression test. Also noticed the Opire reward needs to be + minimum — if you'd like to set it up, I can re-claim the issue.

@zhuyh1606-oss

Copy link
Copy Markdown
Author

Hi @jaasielitaigq, just following up on this PR. It's been open for a while and is ready for merge. Could you please review and merge when you have time? Thanks!

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.

1 participant