Spec-Zone.ru › Ruby on Rails 4.1

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

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

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

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

|
+-- Book
|    |
|    +-- ScaryBook
|    +-- GoodBook
+-- Author
+-- BankAccount

Предположим, что модель Book должна подключаться к отдельной базе данных (то есть к базе данных, отличной от основной). Тогда Book, ScaryBook и GoodBook будут использовать один и тот же пул соединений. Аналогично, Author и BankAccount будут использовать один и тот же пул соединений. Однако, пул соединений, используемый Author/BankAccount, не тот же, что и используемый Book/ScaryBook/GoodBook.

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

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

new() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 483
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?() Показать исходный код

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

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

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

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

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

# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 546
def connected?(klass)
  conn = retrieve_connection_pool(klass)
  conn && conn.connected?
end
connection_pool_list() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 495
def connection_pool_list
  owner_to_pool.values.compact
end
connection_pools() Показать исходный код
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 499
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.)"
  )
  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 507
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) Показать исходный код

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

# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 555
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
retrieve_connection_pool(klass) Показать исходный код

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

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

# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 573
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

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

Spec-Zone.ru

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