Skip to content

Instantly share code, notes, and snippets.

@matsukaz
Last active October 22, 2024 06:09

Revisions

  1. matsukaz revised this gist Jul 31, 2017. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions application.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    module xxx
    class Application < Rails::Application

    #(中略)

    config.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement,
    'ActiveRecord::ConnectionAdapters::ReconnectOnErrorManagement'
    end
    end
  2. matsukaz created this gist Jul 31, 2017.
    40 changes: 40 additions & 0 deletions reconnect_on_error_management.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    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