Spec-Zone.ru › Ruby on Rails 6.1

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

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

Абстрактный класс хранилища кэша. Существует множество реализаций хранилищ кэша, каждая с собственными дополнительными функциями. См. классы в модуле 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 . Массивы и хэши также могут использоваться в качестве ключей. Элементы будут разделены слешами, а элементы внутри Hash будут отсортированы по ключу для обеспечения согласованности.

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

Нулевые значения могут быть кэшированы.

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

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

Константы

DEFAULT_CODER

Атрибуты

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

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

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

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

Методы экземпляров (Public)

cleanup(options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 541
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 551
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 532
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 477
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 514
def delete_matched(matcher, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
end

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

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

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

delete_multi(names, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 488
def delete_multi(names, options = nil)
  options = merged_options(options)
  names.map! { |key| normalize_key(key, options) }

  instrument :delete_multi, names do
    delete_multi_entries(names, **options)
  end
end

Удаляет несколько записей из кэша.

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

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

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

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

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

fetch(name, options = nil, &block) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 320
def fetch(name, options = nil, &block)
  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, event: payload) unless options[:force]
      entry = handle_expired_entry(cached_entry, key, options)
      entry = nil if entry && entry.mismatched?(normalize_version(name, 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, &block)
    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.

Установление skip_nil: true не будет кэшировать результат nil:

cache.fetch('foo') { nil }
cache.fetch('bar', skip_nil: true) { nil }
cache.exist?('foo') # => true
cache.exist?('bar') # => false

Установление compress: false отключает сжатие записи кэша.

Установление :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

Установка :version проверяет, что кэш, хранящийся под name, имеет ту же версию. В случае несовпадения возвращается nil, несмотря на содержимое. Эта функция используется для поддержки переиспользуемых ключей кэша.

Установка :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.seconds) do
    sleep 1
    'new value 1'
  end
end

Thread.new do
  val_2 = cache.fetch('foo', race_condition_ttl: 10.seconds) 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 440
def fetch_multi(*names)
  raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?

  options = names.extract_options!
  options = merged_options(options)

  instrument :read_multi, names, options do |payload|
    reads   = read_multi_entries(names, **options)
    writes  = {}
    ordered = names.index_with do |name|
      reads.fetch(name) { writes[name] = yield(name) }
    end

    payload[:hits] = reads.keys
    payload[:super_operation] = :fetch_multi

    write_multi(writes, options)

    ordered
  end
end

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

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

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" }

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

cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
  "buzz"
end
# => {"fizz"=>"buzz"}
cache.read("fizz")
# => "buzz"
sleep(6)
cache.read("fizz")
# => nil
increment(name, amount = 1, options = nil) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 523
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 200
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 355
def read(name, options = nil)
  options = merged_options(options)
  key     = normalize_key(name, options)
  version = normalize_version(name, options)

  instrument(:read, name, options) do |payload|
    entry = read_entry(key, **options, event: payload)

    if entry
      if entry.expired?
        delete_entry(key, **options)
        payload[:hit] = false if payload
        nil
      elsif entry.mismatched?(version)
        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.

Обратите внимание, что если данные были записаны с параметрами :expires_in или :version, обе эти условия применяются перед возвратом данных.

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

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

  instrument :read_multi, names, options do |payload|
    read_multi_entries(names, **options, event: payload).tap do |results|
      payload[:hits] = results.keys
    end
  end
end

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

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

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

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

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

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

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

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

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

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

  instrument :write_multi, hash, options do |payload|
    entries = hash.each_with_object({}) do |(name, value), memo|
      memo[normalize_key(name, options)] = Entry.new(value, **options.merge(version: normalize_version(name, options)))
    end

    write_multi_entries entries, **options
  end
end

Cache API хранилища для записи нескольких значений одновременно.

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

key_matcher(pattern, options) Показать исходный код
# File activesupport/lib/active_support/cache.rb, line 560
def key_matcher(pattern, options) # :doc:
  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–2020 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

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