Rails: alterna a conexão em cada solicitação, mas mantém um pool de conexão

Em nosso aplicativo Rails, precisamos usar bancos de dados diferentes, dependendo do subdomínio da solicitação (banco de dados diferente por país).

Agora estamos fazendo algo parecido com o que é recomendado emessa questão. Isto é, chamandoActiveRecord::Base.establish_connection em cada pedido.

Masparece ActiveRecord::Base.establish_connection desativa o conjunto de conexões atual e estabelece uma nova conexão sempre que é chamado.

Fiz este benchmark rápido para ver se havia alguma diferença significativa entre o callestablish_connection cada vez e tendo as conexões já estabelecidas:

require 'benchmark/ips'

$config = Rails.configuration.database_configuration[Rails.env]
$db1_config = $config.dup.update('database' => 'db1')
$db2_config = $config.dup.update('database' => 'db2')

# Method 1: call establish_connection on each "request".
Benchmark.ips do |r|
  r.report('establish_connection:') do
    # Simulate two requests, one for each DB.
    ActiveRecord::Base.establish_connection($db1_config)
    MyModel.count # A little query to force the DB connection to establish.
    ActiveRecord::Base.establish_connection($db2_config)
    MyModel.count
  end
end

# Method 2: Have different subclasses of my models, one for each DB, and 
# call establish_connection only once
class MyModelDb1 < MyModel
  establish_connection($db1_config)
end

class MyModelDb2 < MyModel
  establish_connection($db2_config)
end

Benchmark.ips do |r|
  r.report('different models:') do
    MyModelDb1.count
    MyModelDb2.count
  end
end

Eu corro este script comrails runner e apontando para um mysql local com alguns milhares de registros nos bancos de dados e os resultados parecem indicar que de fato existe uma grande diferença (de uma ordem de grandeza) entre os dois métodos (BTW, não tenho certeza se o benchmark é válido ou eu estraguei tudo e, portanto, os resultados são enganosos):

Calculating -------------------------------------
establish_connection: 8 i/100ms
-------------------------------------------------
establish_connection: 117.9 (±26.3%) i/s -        544 in   5.001575s
Calculating -------------------------------------
    different models:  119 i/100ms
-------------------------------------------------
    different models:  1299.4 (±22.1%) i/s -       6188 in   5.039483s

Então, basicamente, eu gostaria de saber se há uma maneira de manter um pool de conexão para cada subdomínio e, em seguida, reutilizar essas conexões em vez de estabelecer uma nova conexão em cada solicitação. Ter uma subclasse de meus modelos para cada subdomínio não é viável, pois há muitos modelos; Eu só quero mudar a conexão para todos os modelos (emActiveRecord::Base)

questionAnswers(2)

yourAnswerToTheQuestion