Skip to content

Instantly share code, notes, and snippets.

@jhoynerk
Forked from matsukaz/application.rb
Last active October 18, 2022 20:30
Show Gist options
  • Save jhoynerk/20b82521095bc1982457044d9868d979 to your computer and use it in GitHub Desktop.
Save jhoynerk/20b82521095bc1982457044d9868d979 to your computer and use it in GitHub Desktop.
Rails 6 connection management to handle Amazon Aurora's failover
# frozen_string_literal: true
require 'active_record/connection_adapters/reconnect_on_error_management'
Rails.application.config.middleware.insert_before ActionDispatch::Executor, ActiveRecord::ConnectionAdapters::ReconnectOnErrorManagement unless Rails.env.test?
# frozen_string_literal: true
module ActiveRecord
module ConnectionAdapters
class ReconnectOnErrorManagement
CONNECTION_ERROR = ['Lost connection', 'gone away', '--read-only'].freeze
CONNECTION_ERROR_RE = /#{CONNECTION_ERROR.map { |w| Regexp.escape(w) }
.join('|')}/.freeze
CONNECTION_ERROR_RE.freeze
def initialize(app)
@app = app
end
def call(env)
testing = env.key?('rack.test')
response = @app.call(env)
response[2] = ::Rack::BodyProxy.new(response[2]) do
ActiveRecord::Base.clear_active_connections! unless testing
end
response
rescue Exception => e
unless testing
if should_clear_all_connections?(e)
ActiveRecord::Base.clear_all_connections!
else
ActiveRecord::Base.clear_active_connections!
end
end
raise
end
def should_clear_all_connections?(e)
return CONNECTION_ERROR_RE === e.message if e.is_a?(ActiveRecord::StatementInvalid)
false
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment