Draft: Fix PostgreSQL server-side connection leak on failed establishment (too many clients)#1219
Open
skunkworker wants to merge 1 commit into
Open
Draft: Fix PostgreSQL server-side connection leak on failed establishment (too many clients)#1219skunkworker wants to merge 1 commit into
skunkworker wants to merge 1 commit into
Conversation
If post-connect setup (PGConnection unwrap / addDataType registration) throws, close the freshly-opened physical connection before propagating, otherwise the server-side backend leaks - the caller only ever sees the exception and never gets a handle to close. Mirrors the native adapter discarding a connection that could not be fully established. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes a server-side connection leak when establishing a PostgreSQL connection fails after the physical backend is already open. Split out of #1216 as an independent, high-priority fix.
AR-JDBC connects eagerly inside the Java connection object's constructor, and
@raw_connectionis only assigned afternew_clientreturns. PostgreSQL'snewConnection()opens the physical backend (super.newConnection()) and then runs post-connect setup (unwrap+addDataTyperegistrations). If any of that setup throws:new_clientnever returns →@raw_connectionstaysnil;attempt_configure_connection→disconnect!runs@raw_connection&.disconnect!, which is a nil no-op → the backend is never closed.The leaked backend persists until non-deterministic JVM GC closes the socket. Under a test/connect loop these accumulate until PostgreSQL
max_connectionsis hit, producingFATAL: sorry, too many clients already, which then cascades intoActiveRecord::ConnectionTimeoutErroras pooled connections are exhausted.Fix
Wrap the post-connect setup in
newConnection()intry { … } catch (SQLException | RuntimeException ex) { connection.close(); throw ex; }, closing the freshly-opened backend deterministically before propagating. This mirrors the native adapter discarding a connection that could not be fully established.super.newConnection()stays outside thetry— if the physical connect itself fails, there is nothing to close.unwrap(PGConnection.class)is now inside thetry— the previous code leaked there too.close()failure is attached viaaddSuppressedso the original exception is preserved.Why this matters now
This is the root cause of the
too many clients alreadycascade seen in the Rails Tests (Postgres) CI jobs (Rails tests intentionally open bad/aborted connections, e.g.test_reconnect_after_bad_connection_on_check_version). The leak is pre-existing — it was simply masked while CI ran onjruby-head(which crashed early). Landing this first makes the other split-out PRs' Rails-test results readable instead of drowning in the cascade.Independent of #1218 (no shared files). Targets
72-stable.🤖 Generated with Claude Code