класс 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. Массивы и хэши также могут быть использованы в качестве ключей. Элементы будут разделяться с помощью слэшей, а элементы внутри хэша будут отсортированы по ключу для обеспечения согласованности.
cache.read('city') == cache.read(:city) # => true
Значения Nil могут быть кэшированы.
Если ваш кэш находится на общей инфраструктуре, вы можете определить имя пространства для ваших записей в кэше. Если пространство имен определено, оно будет добавляться в качестве префикса к каждому ключу. Пространство имен может быть статическим значением или процедурой. Если это процедура, она будет вызываться при оценке каждого ключа, чтобы вы могли использовать логику приложения для обновления ключей.
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 КБ.
Атрибуты
Публичные методы класса
# File activesupport/lib/active_support/cache.rb, line 187 def self.instrument Thread.current[:instrument_cache_store] || false end
Установите в true значение, если хранилища кэша должны быть инструментированы. Значение по умолчанию - false.
# File activesupport/lib/active_support/cache.rb, line 183 def self.instrument=(boolean) Thread.current[:instrument_cache_store] = boolean end
Создать новый кэш. Параметры будут переданы любому вызову метода записи, кроме :namespace, который может быть использован для установки глобального пространства имен для кэша.
# File activesupport/lib/active_support/cache.rb, line 163
def initialize(options = nil)
@options = options ? options.dup : {}
end Публичные методы экземпляра
Очистить кэш, удалив просроченные записи.
Параметры передаются в базовую реализацию кэша.
Не все реализации могут поддерживать этот метод.
# File activesupport/lib/active_support/cache.rb, line 448
def cleanup(options = nil)
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
end Очистить весь кэш. Будьте осторожны с этим методом, так как он может повлиять на другие процессы, если используется общий кэш.
Хэш опций передается в базовую реализацию кэша.
Не все реализации могут поддерживать этот метод.
# File activesupport/lib/active_support/cache.rb, line 458
def clear(options = nil)
raise NotImplementedError.new("#{self.class.name} does not support clear")
end Уменьшить целое значение в кэше.
Параметры передаются в базовую реализацию кэша.
Не все реализации могут поддерживать этот метод.
# File activesupport/lib/active_support/cache.rb, line 439
def decrement(name, amount = 1, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support decrement")
end Удаляет запись из кэша. Возвращает true если запись была удалена.
Параметры передаются в базовую реализацию кэша.
# File activesupport/lib/active_support/cache.rb, line 396
def delete(name, options = nil)
options = merged_options(options)
instrument(:delete, name) do
delete_entry(namespaced_key(name, options), options)
end
end Удалить все записи с ключами, соответствующими шаблону.
Параметры передаются в базовую реализацию кэша.
Не все реализации могут поддерживать этот метод.
# File activesupport/lib/active_support/cache.rb, line 421
def delete_matched(matcher, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
end Возвращает true если кэш содержит запись для данного ключа.
Параметры передаются в базовую реализацию кэша.
# File activesupport/lib/active_support/cache.rb, line 407
def exist?(name, options = nil)
options = merged_options(options)
instrument(:exist?, name) do
entry = read_entry(namespaced_key(name, options), options)
(entry && !entry.expired?) || false
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 заставит произойти промах кэша:
cache.write('today', 'Monday')
cache.fetch('today', force: true) # => nil
Установка :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
# val_1 => "new value 1"
# val_2 => "original value"
# sleep 10 # First thread extend the life of cache by another 10 seconds
# cache.fetch('foo') => "new value 1"
Другие параметры будут обработаны конкретной реализацией хранилища кэша. Внутренне, вызовы fetch читают запись и вызывают 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"
# File activesupport/lib/active_support/cache.rb, line 285
def fetch(name, options = nil)
if block_given?
options = merged_options(options)
key = namespaced_key(name, options)
cached_entry = find_cached_entry(key, name, options) unless options[:force]
entry = handle_expired_entry(cached_entry, key, options)
if entry
get_entry_value(entry, name, options)
else
save_block_result_to_cache(name, options) { |_name| yield _name }
end
else
read(name, options)
end
end Извлекает данные из кэша, используя заданные ключи. Если в кэше есть данные с данными ключами, то эти данные возвращаются. В противном случае вызывается переданный блок для каждого ключа, для которого данных не было, и результат будет записан в кэш и возвращен.
Параметры передаются в базовую реализацию кэша.
Возвращает массив с данными для каждого из имен. Например:
cache.write("bim", "bam")
cache.fetch_multi("bim", "boom") {|key| key * 2 }
# => ["bam", "boomboom"]
# File activesupport/lib/active_support/cache.rb, line 366
def fetch_multi(*names)
options = names.extract_options!
options = merged_options(options)
results = read_multi(*names, options)
names.map do |name|
results.fetch(name) do
value = yield name
write(name, value, options)
value
end
end
end Увеличить целое значение в кэше.
Параметры передаются в базовую реализацию кэша.
Не все реализации могут поддерживать этот метод.
# File activesupport/lib/active_support/cache.rb, line 430
def increment(name, amount = 1, options = nil)
raise NotImplementedError.new("#{self.class.name} does not support increment")
end Отключить регистратор в блоке.
# File activesupport/lib/active_support/cache.rb, line 174 def mute previous_silence, @silence = defined?(@silence) && @silence, true yield ensure @silence = previous_silence end
Извлекает данные из кэша, используя заданный ключ. Если в кэше есть данные с данным ключом, то эти данные возвращаются. В противном случае, возвращается nil.
Параметры передаются в базовую реализацию кэша.
# File activesupport/lib/active_support/cache.rb, line 308
def read(name, options = nil)
options = merged_options(options)
key = namespaced_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 Одновременное чтение нескольких значений из кэша. Параметры можно передать в последнем аргументе.
Некоторые реализации кэша могут оптимизировать этот метод.
Возвращает хэш, сопоставляющий предоставленные имена с найденными значениями.
# File activesupport/lib/active_support/cache.rb, line 335
def read_multi(*names)
options = names.extract_options!
options = merged_options(options)
results = {}
names.each do |name|
key = namespaced_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 Отключить регистратор.
# File activesupport/lib/active_support/cache.rb, line 168 def silence! @silence = true self end
Записывает значение в кэш по ключу.
Параметры передаются в базовую реализацию кэша.
# File activesupport/lib/active_support/cache.rb, line 384
def write(name, value, options = nil)
options = merged_options(options)
instrument(:write, name, options) do
entry = Entry.new(value, options)
write_entry(namespaced_key(name, options), entry, options)
end
end Защищенные методы экземпляра
Добавить определенное в опциях пространство имен к шаблону, предназначенному для соответствия ключам. Реализации, поддерживающие #delete_matched, должны вызывать этот метод для преобразования шаблона, соответствующего именам, в шаблон, соответствующий именам с пространством имен.
# File activesupport/lib/active_support/cache.rb, line 467
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
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.