Spec-Zone.ru › Ruby on Rails 5.0

класс ActiveSupport::Cache::Store

Родитель:
Object

Абстрактный класс кэша. Существует множество реализаций кэша, каждая со своими дополнительными функциями. См. классы в модуле ActiveSupport::Cache, например ActiveSupport::Cache::MemCacheStore. MemCacheStore в настоящее время является наиболее популярным кэшем для крупных сайтов в производстве.

Некоторые реализации могут не поддерживать все методы, кроме основных методов кэширования fetch, write, read, exist?, и delete.

ActiveSupport::Cache::Store может хранить любые сериализуемые объекты Ruby.

cache = ActiveSupport::Cache::MemoryStore.new

cache.read('city')   # => nil
cache.write('city', "Duckburgh")
cache.read('city')   # => "Duckburgh"

Ключи всегда преобразуются в строки и чувствительны к регистру. Когда объект задан в качестве ключа и имеет определённый метод cache_key, этот метод будет вызван для определения ключа. В противном случае будет вызван метод to_param. Массивы и хеши также могут быть использованы в качестве ключей. Элементы будут разделены с помощью слешей, а элементы в хеше будут отсортированы по ключу для обеспечения согласованности.

cache.read('city') == cache.read(:city)   # => true

Значения Nil могут быть помещены в кэш.

Если ваш кэш находится на общем инфраструктуре, вы можете определить пространство имён для ваших записей в кэше. Если пространство имён определено, оно будет добавлено в префикс к каждому ключу. Пространство имён может быть либо статической величиной, либо Proc. Если это Proc, он будет вызываться при каждом оценивании ключа, чтобы вы могли использовать логику приложения для удаления ключей.

cache.namespace = -> { @last_mod_time }  # Set the namespace to a variable
@last_mod_time = Time.now  # Invalidate the entire cache by changing namespace

Кэши также могут хранить значения в сжатом формате, чтобы экономить место и сократить время, затрачиваемое на отправку данных. Поскольку есть накладные расходы, значения должны быть достаточно большими, чтобы оправдать сжатие. Чтобы включить сжатие, передайте compress: true в инициализаторе или в качестве параметра к fetch или write. Чтобы указать порог, при котором значения будут сжиматься, установите параметр :compress_threshold. Пороговое значение по умолчанию составляет 16К.

Атрибуты

options[R]
silence[R]
silence?[R]

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

new(options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 164
def initialize(options = nil)
  @options = options ? options.dup : {}
end

Создаёт новый кэш. Параметры будут переданы любому методу записи, за исключением :namespace, который может быть использован для установки глобального пространства имён для кэша.

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

cleanup(options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 457
def cleanup(options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support cleanup")
end

Очищает кэш, удаляя просроченные записи.

Параметры передаются в базовую реализацию кэша.

Не все реализации могут поддерживать этот метод.

clear(options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 467
def clear(options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support clear")
end

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

Хеш параметров передается в базовую реализацию кэша.

Не все реализации могут поддерживать этот метод.

decrement(name, amount = 1, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 448
def decrement(name, amount = 1, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support decrement")
end

Уменьшает целочисленное значение в кэше.

Параметры передаются в базовую реализацию кэша.

Не все реализации могут поддерживать этот метод.

delete(name, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 405
def delete(name, options = nil)
  options = merged_options(options)

  instrument(:delete, name) do
    delete_entry(normalize_key(name, options), options)
  end
end

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

Параметры передаются в базовую реализацию кэша.

delete_matched(matcher, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 430
def delete_matched(matcher, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
end

Удаляет все записи с ключами, соответствующими шаблону.

Параметры передаются в базовую реализацию кэша.

Не все реализации могут поддерживать этот метод.

exist?(name, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 416
def exist?(name, options = nil)
  options = merged_options(options)

  instrument(:exist?, name) do
    entry = read_entry(normalize_key(name, options), options)
    (entry && !entry.expired?) || false
  end
end

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

Параметры передаются в базовую реализацию кэша.

fetch(name, options = nil) { |_name| ... } Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 284
def fetch(name, options = nil)
  if block_given?
    options = merged_options(options)
    key = normalize_key(name, options)

    entry = nil
    instrument(:read, name, options) do |payload|
      cached_entry = read_entry(key, options) unless options[:force]
      entry = handle_expired_entry(cached_entry, key, options)
      payload[:super_operation] = :fetch if payload
      payload[:hit] = !!entry if payload
    end

    if entry
      get_entry_value(entry, name, options)
    else
      save_block_result_to_cache(name, options) { |_name| yield _name }
    end
  elsif options && options[:force]
    raise ArgumentError, 'Missing block: Calling `Cache#fetch` with `force: true` requires a block.'
  else
    read(name, options)
  end
end

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

Если таких данных в кэше нет (промах кэша), то возвращается nil. Однако, если передан блок, этот блок будет передан ключ и выполнен в случае промаха кэша. Возвращаемое значение блока будет записано в кэш под заданным ключом кэша, и это возвращаемое значение будет возвращено.

cache.write('today', 'Monday')
cache.fetch('today')  # => "Monday"

cache.fetch('city')   # => nil
cache.fetch('city') do
  'Duckburgh'
end
cache.fetch('city')   # => "Duckburgh"

Вы также можете указать дополнительные параметры через аргумент options. Установка force: true принудительно создаёт «промах» кэша, то есть мы обрабатываем значение кэша как отсутствующее, даже если оно присутствует. Передача блока требуется, когда `force` имеет значение true, поэтому это всегда приводит к записи в кэш.

cache.write('today', 'Monday')
cache.fetch('today', force: true) { 'Tuesday' } # => 'Tuesday'
cache.fetch('today', force: true) # => ArgumentError

Опция `:force` полезна, когда вы вызываете другой метод, чтобы узнать, следует ли принудительно производить запись в кэш. В противном случае яснее просто вызвать `Cache#write`.

Установка :compress сохранит большой набор записей кэша в сжатом формате.

Установка :expires_in задаст время истечения срока действия записи в кэше. Все кэши поддерживают автоматическое истечение срока действия содержимого после заданного количества секунд. Это значение может быть указано как опция конструктору (в этом случае все записи будут затронуты), или оно может быть предоставлено методам fetch или write для воздействия только на одну запись.

cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry

Установка :race_condition_ttl очень полезна в ситуациях, когда запись в кэше используется очень часто и находится под большой нагрузкой. Если кэш истекает, и из-за большой нагрузки несколько разных процессов попытаются прочитать данные непосредственно, а затем все они попытаются записать в кэш. Для предотвращения такой ситуации первый процесс, который обнаружит просроченную запись в кэше, увеличит время истечения срока действия кэша на значение, заданное в :race_condition_ttl. Да, этот процесс продлевает срок жизни устаревшего значения на несколько дополнительных секунд. Из-за увеличенного срока жизни предыдущего кэша другие процессы будут продолжать использовать слегка устаревшие данные чуть дольше. Тем временем первый процесс выполнит запись нового значения в кэш. После этого все процессы начнут получать новое значение. Ключ состоит в том, чтобы держать :race_condition_ttl небольшим.

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

# Set all values to expire after one minute.
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)

cache.write('foo', 'original value')
val_1 = nil
val_2 = nil
sleep 60

Thread.new do
  val_1 = cache.fetch('foo', race_condition_ttl: 10) do
    sleep 1
    'new value 1'
  end
end

Thread.new do
  val_2 = cache.fetch('foo', race_condition_ttl: 10) do
    'new value 2'
  end
end

cache.fetch('foo') # => "original value"
sleep 10 # First thread extended the life of cache by another 10 seconds
cache.fetch('foo') # => "new value 1"
val_1 # => "new value 1"
val_2 # => "original value"

Другие параметры будут обрабатываться конкретной реализацией хранилища кэша. Внутренне, вызов fetch вызывает read_entry, а при промахе кэша вызывает write_entry. options будет передан вызовам read и write.

Например, метод write MemCacheStore поддерживает опцию :raw, которая сообщает серверу memcached хранить все значения в виде строк. Мы также можем использовать эту опцию с fetch:

cache = ActiveSupport::Cache::MemCacheStore.new
cache.fetch("foo", force: true, raw: true) do
  :bar
end
cache.fetch('foo') # => "bar"
fetch_multi(*names) { |name| ... } Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 376
def fetch_multi(*names)
  options = names.extract_options!
  options = merged_options(options)
  results = read_multi(*names, options)

  names.each_with_object({}) do |name, memo|
    memo[name] = results.fetch(name) do
      value = yield name
      write(name, value, options)
      value
    end
  end
end

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

Параметры передаются в базовую реализацию кэша.

Возвращает хеш с данными для каждого из имён. Например:

cache.write("bim", "bam")
cache.fetch_multi("bim", "unknown_key") do |key|
  "Fallback value for key: #{key}"
end
# => { "bim" => "bam",
#      "unknown_key" => "Fallback value for key: unknown_key" }
increment(name, amount = 1, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 439
def increment(name, amount = 1, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support increment")
end

Увеличивает целочисленное значение в кэше.

Параметры передаются в базовую реализацию кэша.

Не все реализации могут поддерживать этот метод.

mute() { || ... } Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 175
def mute
  previous_silence, @silence = defined?(@silence) && @silence, true
  yield
ensure
  @silence = previous_silence
end

Отключает регистратор внутри блока.

read(name, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 314
def read(name, options = nil)
  options = merged_options(options)
  key = normalize_key(name, options)
  instrument(:read, name, options) do |payload|
    entry = read_entry(key, options)
    if entry
      if entry.expired?
        delete_entry(key, options)
        payload[:hit] = false if payload
        nil
      else
        payload[:hit] = true if payload
        entry.value
      end
    else
      payload[:hit] = false if payload
      nil
    end
  end
end

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

Параметры передаются в базовую реализацию кэша.

read_multi(*names) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 341
def read_multi(*names)
  options = names.extract_options!
  options = merged_options(options)

  results = {}
  names.each do |name|
    key = normalize_key(name, options)
    entry = read_entry(key, options)
    if entry
      if entry.expired?
        delete_entry(key, options)
      else
        results[name] = entry.value
      end
    end
  end
  results
end

Читает несколько значений одновременно из кэша. Параметры можно передать в последнем аргументе.

Некоторые реализации кэша могут оптимизировать этот метод.

Возвращает хеш, сопоставляющий предоставленные имена найденным значениям.

silence!() Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 169
def silence!
  @silence = true
  self
end

Отключает регистратор.

write(name, value, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 393
def write(name, value, options = nil)
  options = merged_options(options)

  instrument(:write, name, options) do
    entry = Entry.new(value, options)
    write_entry(normalize_key(name, options), entry, options)
  end
end

Записывает значение в кэш с заданным ключом.

Параметры передаются в базовую реализацию кэша.

Защищённые методы экземпляра

key_matcher(pattern, options) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 476
def key_matcher(pattern, options)
  prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
  if prefix
    source = pattern.source
    if source.start_with?('^')
      source = source[1, source.length]
    else
      source = ".*#{source[0, source.length]}"
    end
    Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
  else
    pattern
  end
end

Добавляет пространство имен, определённое в параметрах, к шаблону, предназначенному для сопоставления ключей. Реализации, которые поддерживают #delete_matched, должны вызывать этот метод для преобразования шаблона, сопоставляющего имена, в шаблон, сопоставляющий именованные ключи.

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

Spec-Zone.ru

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