Spec-Zone.ru › Ruby on Rails 5.2

класс ActiveRecord::ConnectionAdapters::ConnectionHandler

Родитель:
Object

ConnectionHandler — это коллекция объектов ConnectionPool. Она используется для хранения отдельных пулов подключений, которые соединяются с различными базами данных.

Например, предположим, что у вас есть 5 моделей с такой иерархией:

class Author < ActiveRecord::Base
end

class BankAccount < ActiveRecord::Base
end

class Book < ActiveRecord::Base
  establish_connection :library_db
end

class ScaryBook < Book
end

class GoodBook < Book
end

И файл database.yml, который выглядит так:

development:
  database: my_application
  host: localhost

library_db:
  database: library
  host: some.library.org

Ваша основная база данных в среде разработки — «my_application», но модель Book подключается к отдельной базе данных под названием «library_db» (это может быть даже база данных на другом компьютере).

Book, ScaryBook и GoodBook будут использовать один и тот же пул подключений к «library_db», в то время как Author, BankAccount и любые другие созданные вами модели будут использовать стандартный пул подключений к «my_application».

Различные пулы подключений управляются одним экземпляром ConnectionHandler, доступным через ActiveRecord::Core.connection_handler. Все модели Active Record используют этот обработчик для определения пула подключений, который они должны использовать.

Класс ConnectionHandler не связан с моделями Active Record, так как он не имеет знания о моделях. Модель должна передать имя спецификации обработчику, чтобы найти правильный пул подключений.

Открытые методы класса

new() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 930
def initialize
  # These caches are keyed by spec.name (ConnectionSpecification#name).
  @owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
    # Discard the parent's connection pools immediately; we have no need
    # of them
    ConnectionHandler.discard_unowned_pools(h)

    h[k] = Concurrent::Map.new(initial_capacity: 2)
  end

  # Backup finalizer: if the forked child never needed a pool, the above
  # early discard has not occurred
  ObjectSpace.define_finalizer self, ConnectionHandler.unowned_pool_finalizer(@owner_to_pool)
end

Открытые методы экземпляра

active_connections?() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 974
def active_connections?
  connection_pool_list.any?(&:active_connection?)
end

Возвращает true, если существуют активные подключения среди пулов подключений, которые управляет ConnectionHandler.

clear_active_connections!() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 981
def clear_active_connections!
  connection_pool_list.each(&:release_connection)
end

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

clear_all_connections!() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 992
def clear_all_connections!
  connection_pool_list.each(&:disconnect!)
end
clear_reloadable_connections!() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 988
def clear_reloadable_connections!
  connection_pool_list.each(&:clear_reloadable_connections!)
end

Очищает кэш, который сопоставляет классы.

См. ActiveRecord::ConnectionAdapters::ConnectionPool#clear_reloadable_connections! для получения подробной информации.

connected?(spec_name) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1015
def connected?(spec_name)
  conn = retrieve_connection_pool(spec_name)
  conn && conn.connected?
end

Возвращает true, если подключение, доступное для этого класса, уже открыто.

connection_pool_list() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 945
def connection_pool_list
  owner_to_pool.values.compact
end
Также алиас: connection_pools
connection_pools()
Псевдоним для: connection_pool_list
establish_connection(config) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 950
def establish_connection(config)
  resolver = ConnectionSpecification::Resolver.new(Base.configurations)
  spec = resolver.spec(config)

  remove_connection(spec.name)

  message_bus = ActiveSupport::Notifications.instrumenter
  payload = {
    connection_id: object_id
  }
  if spec
    payload[:spec_name] = spec.name
    payload[:config] = spec.config
  end

  message_bus.instrument("!connection.active_record", payload) do
    owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec)
  end

  owner_to_pool[spec.name]
end
flush_idle_connections!() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 999
def flush_idle_connections!
  connection_pool_list.each(&:flush!)
end

Отключает все в настоящее время неиспользуемые подключения.

См. ActiveRecord::ConnectionAdapters::ConnectionPool#flush! для получения подробной информации.

remove_connection(spec_name) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1024
def remove_connection(spec_name)
  if pool = owner_to_pool.delete(spec_name)
    pool.automatic_reconnect = false
    pool.disconnect!
    pool.spec.config
  end
end

Удаляет подключение для этого класса. Это закроет активное подключение и определенное подключение (если они существуют). Результат может быть использован в качестве аргумента для establish_connection для легкого повторного подключения.

retrieve_connection_pool(spec_name) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1035
def retrieve_connection_pool(spec_name)
  owner_to_pool.fetch(spec_name) do
    # Check if a connection was previously established in an ancestor process,
    # which may have been forked.
    if ancestor_pool = pool_from_any_process_for(spec_name)
      # A connection was established in an ancestor process that must have
      # subsequently forked. We can't reuse the connection, but we can copy
      # the specification and establish a new connection with it.
      establish_connection(ancestor_pool.spec.to_hash).tap do |pool|
        pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache
      end
    else
      owner_to_pool[spec_name] = nil
    end
  end
end

Извлечение пула подключений происходит часто, поэтому мы кэшируем его в @owner_to_pool. Это делает извлечение пула подключений O(1) после того, как процесс прогреется. При установлении или удалении подключения мы аннулируем кэш.

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API