Замена ActiveRecord:: ConnectionAdapters:: ConnectionManagement в ActiveRecord 5

Мы обновляем приложение Sinatra из ActiveRecord 4 до ActiveRecord 5. Ранее мы имели следующую строку:

use ActiveRecord::ConnectionAdapters::ConnectionManagement

Это связано с тем, что соединения не очищались после завершения запросов. Вот предварительная дискуссия по этой теме:

Начиная с ActiveRecord 5, эта строка больше не работает. Этот разговор в состояниях рельсов:

Это было удалено в пользу API-интерфейса Executor и Reloader. Что промежуточное программное обеспечение, которое было удалено, не было частью публичного API. если ты хотите использовать ту внешнюю Rails, что вам нужно сделать.

Означает ли это, что если кто-то будет использовать ActiveRecord 5 с Sinatra, соединения будут снова "пропущены" или оставлены без возврата в пул после запроса, если разработчик не заново создаст удаленное промежуточное программное обеспечение?

В примере с Sinatra, так ли теперь, что нам нужно включить эту строку в ActiveRecord 5?

after do
  ActiveRecord::Base.clear_active_connections!
end

Это подразумевается в связанном потоке, но я хочу получить определенный ответ, который я могу вернуть к своей команде разработчиков.

Ответ 1

Вы правы, промежуточное ПО ConnectionManagement было удалено из ActiveRecord 5 (PR # 23807), поэтому вам нужно будет при настройке ActiveRecord за пределами Rails. Существует несколько способов сделать это:

1. ConnectionManagement Средство промежуточного уровня стойки

ConnectionManagement класс не очень сложный. Вы можете скопировать и вставить реализацию где-нибудь в локальном приложении и включить ее как обычно в стек промежуточного программного обеспечения стойки:

class ConnectionManagement
  def initialize(app)
    @app = app
  end

  def call(env)
    testing = env['rack.test']

    status, headers, body = @app.call(env)
    proxy = ::Rack::BodyProxy.new(body) do
      ActiveRecord::Base.clear_active_connections! unless testing
    end
    [status, headers, proxy]
  rescue Exception
    ActiveRecord::Base.clear_active_connections! unless testing
    raise
  end
end

use ConnectionManagement

2. (Sinatra-specific) подключение-управление after hook

В приложении Sinatra блок, который вы предложили, должен работать:

after do
  ActiveRecord::Base.clear_active_connections!
end

Обратите внимание, что это также подход используемый в настоящее время sinatra-activerecord для поддержки ActiveRecord 5 (см. вопрос # 73).

3. ActionDispatch::Executor Средство промежуточного уровня стойки

Наконец, вы можете использовать тот же код. Rails теперь использует для управления соединениями ActiveRecord, добавляя ActionDispatch::Executor в свой стековый промежуточный пакет и вызывая ActiveRecord::QueryCache#install_executor_hooks, чтобы вставить крючок, используемый для очистки соединений ActiveRecord:

require 'action_dispatch/middleware/executor'
use ActionDispatch::Executor, ActiveSupport::Executor
ActiveRecord::QueryCache.install_executor_hooks