active_record_postgresql_xverify
It is a library to solve Amazon RDS failover problems.
Note
This library does not retry queries. Just reconnect.
Caution
The timing of verify has changed, so it probably won't work properly with Rails 7.1. cf. rails/rails#44576
How it works
Installation
Add this line to your application's Gemfile:
gem 'active_record_postgresql_xverify'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_record_postgresql_xverify
Usage
#!/usr/bin/env ruby
require 'active_record'
require 'active_record_postgresql_xverify'
require 'logger'
ActiveRecord::Base.establish_connection(
adapter: 'postgresql',
host: '127.0.0.1',
port: 5432,
username: 'root',
database: 'bookshelf',
)
ActiveRecord::Base.logger = Logger.new($stdout)
ActiveRecord::Base.logger.formatter = proc {|_, _, _, message| "#{message}\n" }
ActiveRecordPostgresqlXverify.verify = ->(conn) do
ping = begin
conn.query ''
true
rescue PG::Error
false
end
ping && false # force reconnect
end
# Default: ->(conn) do
# begin
# conn.query ''
# true
# rescue PG::Error
# false
# end
ActiveRecordPostgresqlXverify.handle_if = ->(config) do
config[:host] == '127.0.0.1'
end
# Default: ->(_) { true }
ActiveRecordPostgresqlXverify.only_on_error = false
# Default: true
# postgres=> CREATE DATABASE bookshelf;
# bookshelf=> CREATE TABLE books (id INT PRIMARY KEY);
class Book < ActiveRecord::Base; end
def pg_backend_pid(model)
conn = model.connection.instance_variable_get(:@connection) || Book.connection.instance_variable_get(:@raw_connection)
conn.backend_pid
end
Book.count
prev_process_id = pg_backend_pid(Book)
ActiveRecord::Base.connection_handler.connection_pool_list.each(&:release_connection)
Book.count
curr_process_id = pg_backend_pid(Book)
p curr_process_id == prev_process_id #=> false
Rails configuration
In config/environments/production.rb
:
ActiveRecordPostgresqlXverify.verify = ->(conn) do
ping = begin
conn.query ''
true
rescue PG::Error
false
end
ping && conn.query('show transaction_read_only').getvalue(0, 0) == 'off'
end
# Same as below:
# ActiveRecordPostgresqlXverify.verify = ActiveRecordPostgresqlXverify::Verifiers::AURORA_MASTER
Test
bundle install
bundle exec appraisal install
docker-compose up -d
bundle exec appraisal ar71 rake