Skip to content

Instantly share code, notes, and snippets.

@matsukaz
Last active October 22, 2024 06:09
Show Gist options
  • Save matsukaz/fb0e0bc47752ebb6f751c79268e1b6f5 to your computer and use it in GitHub Desktop.
Save matsukaz/fb0e0bc47752ebb6f751c79268e1b6f5 to your computer and use it in GitHub Desktop.
Rails connection management to handle Amazon Aurora's failover
module xxx
class Application < Rails::Application
#(中略)
config.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement,
'ActiveRecord::ConnectionAdapters::ReconnectOnErrorManagement'
end
end
module ActiveRecord
module ConnectionAdapters
class ReconnectOnErrorManagement
CONNECTION_ERROR = ['Lost connection', 'gone away', '--read-only']
CONNECTION_ERROR_RE = /#{CONNECTION_ERROR.map{|w|Regexp.escape(w)}.join('|')}/
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)
if e.kind_of?(ActiveRecord::StatementInvalid)
return CONNECTION_ERROR_RE === e.message
end
return false
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment