Подтвердить что ты не робот

Понимание того, как install_connection работает в ActiveRecord

Этот код был взят из ActiveRecord 2.3.14 gem class ConnectionHandler

def establish_connection(name, spec)
  @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
end

Кажется, каждый раз ruby ​​вызывает establish_connection на модели, создавая новый пул соединений.

Мой вопрос:

Если у меня есть 5 моделей, которые используют establish_connection в той же базе данных, достаточно ли Rails достаточно, чтобы выбрать уже существующий пул, а создать новый с теми же учетными данными? Это также происходит, если мои 5 моделей являются подклассами некоторого абстрактного класса, который использует establish_connection? Всегда ли будет выбирать соединение с @connection_pools, если оно существует?

Обновление 1

Я говорю о конкретном примере. У вас есть 5 моделей с 5 различными соединениями, каждый раз, когда Rails использует модель, она выполняет establish_connection. Если посмотреть на код в ActiveRecord, когда он выполнит establish_connection, он создаст новый пул с подключениями к этому конкретному соединению. Мне интересно, каждый раз Rails вызывает модель establish_connection, создает ли новый пул или использует существующий.

Пример: вы приходите на мой сайт и видите список продуктов. Вы только что нажали на действие, которое вызывает Product.all, которое выполняет establish_connection в какой-либо базе данных на Amazon. Затем я прихожу к списку продуктов, что происходит? Ухватить ли я установленное соединение или создать новый пул с этим соединением?

Обновление 2

Я предполагаю, что Rails впервые загружает мои модели, создавая пулы с разными соединениями. После того, как я использую некоторый Model.method, он просто захватывает соединение, связанное с моделью, и выполняет этот метод.

Я не уверен, что произойдет, когда 2 модели имеют два равных соединения (не в абстрактном классе, а в классе self). Будет ли это создавать два одинаковых пула соединений или достаточно ActiveRecord, чтобы поймать этот случай?

4b9b3361

Ответ 1

Вам действительно не нужно вызывать establish_connection для каждой модели. Вы можете просто сделать следующее:

ActiveRecord::Base.establish_connection(
 { :adapter => 'mysql2',
   :database => 'some_database',
   :host => 'localhost',
   :username => 'root',
   :password => "" }
)

и у вас будет доступ к соединению. (Этот фрагмент кода был извлечен из реального кода (кроме имени базы данных:))).
Но по API я считаю, что Rails не использует существующее соединение с другой моделью (исправьте меня, если я ошибаюсь).
Также здесь ссылка на документацию. Вы можете больше узнать о подключении.
Надеюсь, я помог вам немного.

Ответ 2

AR вызывает connect_connection только один раз, для ActiveRecord:: Base. Все подклассы используют одно соединение.

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

class MyMainUser < ActiveRecord::Base; end 
class MyOtherDb < ActiveRecord::Base; end
class MyOtherUser < MyOtherDb; end

MyOtherDb.establish_connection ...

MyMainUser.first # uses default db
MyOtherUser.first # uses other db

Вы не можете делать запросы, которые будут перекрещивать базы данных.

Ответ 3

Этот комментарий:

# Check-out a database connection from the pool, indicating that you want
# to use it. You should call #checkin when you no longer need this.
#
# This is done by either returning an existing connection, or by creating
# a new connection. If the maximum number of connections for this pool has
# already been reached, but the pool is empty (i.e. they're all being used),
# then this method will wait until a thread has checked in a connection.
# The wait time is bounded however: if no connection can be checked out
# within the timeout specified for this pool, then a ConnectionTimeoutError
# exception will be raised.

from: https://github.com/rails/rails/blob/dd944cbf5879e675fff541d1be7c7eb6c3382d01/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L242-251

Должен объяснить ситуацию