Skip to content

Commit

Permalink
Merge pull request rails#49802 from composerinteralia/postgres-unreco…
Browse files Browse the repository at this point in the history
…verable-connection-error

Recover from failed connections in PostgreSQL
  • Loading branch information
matthewd authored Nov 6, 2023
2 parents 995092e + 73edae7 commit c0e67e6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -903,10 +903,10 @@ def exec_cache(sql, name, binds, async:, allow_retry:, materialize_transactions:

update_typemap_for_default_timezone

stmt_key = prepare_statement(sql, binds)
type_casted_binds = type_casted_binds(binds)

with_raw_connection do |conn|
stmt_key = prepare_statement(sql, binds, conn)
type_casted_binds = type_casted_binds(binds)

log(sql, name, binds, type_casted_binds, stmt_key, async: async) do
conn.exec_prepared(stmt_key, type_casted_binds)
end
Expand Down Expand Up @@ -956,22 +956,20 @@ def sql_key(sql)

# Prepare the statement if it hasn't been prepared, return
# the statement key.
def prepare_statement(sql, binds)
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
sql_key = sql_key(sql)
unless @statements.key? sql_key
nextkey = @statements.next_key
begin
conn.prepare nextkey, sql
rescue => e
raise translate_exception_class(e, sql, binds)
end
# Clear the queue
conn.get_last_result
@statements[sql_key] = nextkey
def prepare_statement(sql, binds, conn)
sql_key = sql_key(sql)
unless @statements.key? sql_key
nextkey = @statements.next_key
begin
conn.prepare nextkey, sql
rescue => e
raise translate_exception_class(e, sql, binds)
end
@statements[sql_key]
# Clear the queue
conn.get_last_result
@statements[sql_key] = nextkey
end
@statements[sql_key]
end

# Connects to a PostgreSQL server and sets up the adapter depending on the
Expand Down
14 changes: 14 additions & 0 deletions activerecord/test/cases/adapter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,20 @@ def teardown
assert_predicate @connection, :active?
end

test "querying after a failed query restores and succeeds" do
Post.first # Connection verified (and prepared statement pool populated if enabled)

remote_disconnect @connection

assert_raises(ActiveRecord::ConnectionFailed) do
Post.first # Connection no longer verified after failed query
end

assert Post.first # Verifying the connection causes a reconnect and the query succeeds

assert_predicate @connection, :active?
end

test "transaction restores after remote disconnection" do
remote_disconnect @connection
Post.transaction do
Expand Down

0 comments on commit c0e67e6

Please sign in to comment.