Spec-Zone.ru › Ruby on Rails 4.2

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

Родитель:
Объект

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

Например, предположим, что у вас есть 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 используют этот обработчик для определения пула соединений, который они должны использовать.

Публичные методы класса

new() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 511
def initialize
  # These caches are keyed by klass.name, NOT klass. Keying them by klass
  # alone would lead to memory leaks in development mode as all previous
  # instances of the class would stay in memory.
  @owner_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k|
    h[k] = ThreadSafe::Cache.new(:initial_capacity => 2)
  end
  @class_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k|
    h[k] = ThreadSafe::Cache.new
  end
end

Публичные методы экземпляра

active_connections?() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 544
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 551
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 560
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 556
def clear_reloadable_connections!
  connection_pool_list.each(&:clear_reloadable_connections!)
end

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

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

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

connection_pool_list() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 523
def connection_pool_list
  owner_to_pool.values.compact
end
connection_pools() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 527
      def connection_pools
        ActiveSupport::Deprecation.warn("          In the next release, this will return the same as `#connection_pool_list`.
          (An array of pools, rather than a hash mapping specs to pools.)
".squish)

        Hash[connection_pool_list.map { |pool| [pool.spec, pool] }]
      end
establish_connection(owner, spec) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 536
def establish_connection(owner, spec)
  @class_to_pool.clear
  raise RuntimeError, "Anonymous class is not allowed." unless owner.name
  owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec)
end
remove_connection(owner) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 587
def remove_connection(owner)
  if pool = owner_to_pool.delete(owner.name)
    @class_to_pool.clear
    pool.automatic_reconnect = false
    pool.disconnect!
    pool.spec.config
  end
end

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

retrieve_connection_pool(klass) Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 605
def retrieve_connection_pool(klass)
  class_to_pool[klass.name] ||= begin
    until pool = pool_for(klass)
      klass = klass.superclass
      break unless klass <= Base
    end

    class_to_pool[klass.name] = pool
  end
end

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

В идеале, мы бы использовали fetch здесь, так как class_to_pool иногда может быть пустым. Однако, бенчмаркинг (gist.github.com/jonleighton/3552829) показал, что fetch значительно медленнее, чем []. Поэтому в случае null-значения кэширование не произойдёт, но это нормально, так как случай null-значения не является распространённым, для которого мы хотели бы оптимизировать.

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

Spec-Zone.ru

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