lib/active_support/cache.rb in activesupport-5.0.7.2 vs lib/active_support/cache.rb in activesupport-5.1.0.beta1
- old
+ new
@@ -1,31 +1,28 @@
-require 'benchmark'
-require 'zlib'
-require 'active_support/core_ext/array/extract_options'
-require 'active_support/core_ext/array/wrap'
-require 'active_support/core_ext/benchmark'
-require 'active_support/core_ext/module/attribute_accessors'
-require 'active_support/core_ext/numeric/bytes'
-require 'active_support/core_ext/numeric/time'
-require 'active_support/core_ext/object/to_param'
-require 'active_support/core_ext/string/inflections'
-require 'active_support/core_ext/string/strip'
+require "zlib"
+require "active_support/core_ext/array/extract_options"
+require "active_support/core_ext/array/wrap"
+require "active_support/core_ext/module/attribute_accessors"
+require "active_support/core_ext/numeric/bytes"
+require "active_support/core_ext/numeric/time"
+require "active_support/core_ext/object/to_param"
+require "active_support/core_ext/string/inflections"
module ActiveSupport
# See ActiveSupport::Cache::Store for documentation.
module Cache
- autoload :FileStore, 'active_support/cache/file_store'
- autoload :MemoryStore, 'active_support/cache/memory_store'
- autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
- autoload :NullStore, 'active_support/cache/null_store'
+ autoload :FileStore, "active_support/cache/file_store"
+ autoload :MemoryStore, "active_support/cache/memory_store"
+ autoload :MemCacheStore, "active_support/cache/mem_cache_store"
+ autoload :NullStore, "active_support/cache/null_store"
# These options mean something to all cache implementations. Individual cache
# implementations may support additional options.
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
module Strategy
- autoload :LocalCache, 'active_support/cache/strategy/local_cache'
+ autoload :LocalCache, "active_support/cache/strategy/local_cache"
end
class << self
# Creates a new Store object according to the given options.
#
@@ -71,12 +68,12 @@
#
# If the +key+ argument provided is an array, or responds to +to_a+, then
# each of elements in the array will be turned into parameters/keys and
# concatenated into a single key. For example:
#
- # expand_cache_key([:foo, :bar]) # => "foo/bar"
- # expand_cache_key([:foo, :bar], "namespace") # => "namespace/foo/bar"
+ # ActiveSupport::Cache.expand_cache_key([:foo, :bar]) # => "foo/bar"
+ # ActiveSupport::Cache.expand_cache_key([:foo, :bar], "namespace") # => "namespace/foo/bar"
#
# The +key+ argument can also respond to +cache_key+ or +to_param+.
def expand_cache_key(key, namespace = nil)
expanded_cache_key = namespace ? "#{namespace}/" : ""
@@ -151,11 +148,11 @@
# large enough to warrant compression. To turn on compression either pass
# <tt>compress: true</tt> in the initializer or as an option to +fetch+
# or +write+. To specify the threshold at which to compress values, set the
# <tt>:compress_threshold</tt> option. The default threshold is 16K.
class Store
- cattr_accessor :logger, :instance_writer => true
+ cattr_accessor :logger, instance_writer: true
attr_reader :silence, :options
alias :silence? :silence
# Creates a new cache. The options will be passed to any write method calls
@@ -198,19 +195,19 @@
# cache.fetch('city') # => "Duckburgh"
#
# You may also specify additional options via the +options+ argument.
# Setting <tt>force: true</tt> forces a cache "miss," meaning we treat
# the cache value as missing even if it's present. Passing a block is
- # required when `force` is true so this always results in a cache write.
+ # required when +force+ is true so this always results in a cache write.
#
# cache.write('today', 'Monday')
# cache.fetch('today', force: true) { 'Tuesday' } # => 'Tuesday'
# cache.fetch('today', force: true) # => ArgumentError
#
- # The `:force` option is useful when you're calling some other method to
+ # The +:force+ option is useful when you're calling some other method to
# ask whether you should force a cache write. Otherwise, it's clearer to
- # just call `Cache#write`.
+ # just call <tt>Cache#write</tt>.
#
# Setting <tt>:compress</tt> will store a large cache entry set by the call
# in a compressed format.
#
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
@@ -248,18 +245,18 @@
# val_1 = nil
# val_2 = nil
# sleep 60
#
# Thread.new do
- # val_1 = cache.fetch('foo', race_condition_ttl: 10) 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) do
+ # val_2 = cache.fetch('foo', race_condition_ttl: 10.seconds) do
# 'new value 2'
# end
# end
#
# cache.fetch('foo') # => "original value"
@@ -298,11 +295,11 @@
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.'
+ raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
else
read(name, options)
end
end
@@ -359,10 +356,13 @@
# Fetches data from the cache, using the given keys. If there is data in
# the cache with the given keys, then that data is returned. Otherwise,
# the supplied block is called for each key for which there was no data,
# and the result will be written to the cache and returned.
+ # Therefore, you need to pass a block that returns the data to be written
+ # to the cache. If you do not want to write the cache when the cache is
+ # not found, use #read_multi.
#
# Options are passed to the underlying cache implementation.
#
# Returns a hash with the data for each of the names. For example:
#
@@ -372,10 +372,12 @@
# end
# # => { "bim" => "bam",
# # "unknown_key" => "Fallback value for key: unknown_key" }
#
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)
results = read_multi(*names, options)
names.each_with_object({}) do |name, memo|
@@ -462,24 +464,24 @@
# affect other processes if shared cache is being used.
#
# The options hash is passed to the underlying cache implementation.
#
# All implementations may not support this method.
- def clear(options = nil)
+ def clear
raise NotImplementedError.new("#{self.class.name} does not support clear")
end
- protected
+ private
# Adds the namespace defined in the options to a pattern designed to
# match keys. Implementations that support delete_matched should call
# this method to translate a pattern that matches names into one that
# matches namespaced keys.
- def key_matcher(pattern, options)
+ 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?('^')
+ if source.start_with?("^")
source = source[1, source.length]
else
source = ".*#{source[0, source.length]}"
end
Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
@@ -488,51 +490,50 @@
end
end
# Reads an entry from the cache implementation. Subclasses must implement
# this method.
- def read_entry(key, options) # :nodoc:
+ def read_entry(key, options)
raise NotImplementedError.new
end
# Writes an entry to the cache implementation. Subclasses must implement
# this method.
- def write_entry(key, entry, options) # :nodoc:
+ def write_entry(key, entry, options)
raise NotImplementedError.new
end
# Deletes an entry from the cache implementation. Subclasses must
# implement this method.
- def delete_entry(key, options) # :nodoc:
+ def delete_entry(key, options)
raise NotImplementedError.new
end
- private
# Merges the default options with ones specific to a method call.
- def merged_options(call_options) # :nodoc:
+ def merged_options(call_options)
if call_options
options.merge(call_options)
else
options.dup
end
end
# Expands key to be a consistent string value. Invokes +cache_key+ if
# object responds to +cache_key+. Otherwise, +to_param+ method will be
# called. If the key is a Hash, then keys will be sorted alphabetically.
- def expanded_key(key) # :nodoc:
+ def expanded_key(key)
return key.cache_key.to_s if key.respond_to?(:cache_key)
case key
when Array
if key.size > 1
- key = key.collect{|element| expanded_key(element)}
+ key = key.collect { |element| expanded_key(element) }
else
key = key.first
end
when Hash
- key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
+ key = key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }
end
key.to_param
end
@@ -544,24 +545,16 @@
prefix = namespace.is_a?(Proc) ? namespace.call : namespace
key = "#{prefix}:#{key}" if prefix
key
end
- def namespaced_key(*args)
- ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc)
- `namespaced_key` is deprecated and will be removed from Rails 5.1.
- Please use `normalize_key` which will return a fully resolved key.
- MESSAGE
- normalize_key(*args)
- end
-
def instrument(operation, key, options = nil)
log { "Cache #{operation}: #{normalize_key(key, options)}#{options.blank? ? "" : " (#{options.inspect})"}" }
- payload = { :key => key }
+ payload = { key: key }
payload.merge!(options) if options.is_a?(Hash)
- ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
+ ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload) { yield(payload) }
end
def log
return unless logger && logger.debug? && !silence?
logger.debug(yield)
@@ -572,20 +565,20 @@
race_ttl = options[:race_condition_ttl].to_i
if (race_ttl > 0) && (Time.now.to_f - entry.expires_at <= race_ttl)
# When an entry has a positive :race_condition_ttl defined, put the stale entry back into the cache
# for a brief period while the entry is being recalculated.
entry.expires_at = Time.now + race_ttl
- write_entry(key, entry, :expires_in => race_ttl * 2)
+ write_entry(key, entry, expires_in: race_ttl * 2)
else
delete_entry(key, options)
end
entry = nil
end
entry
end
def get_entry_value(entry, name, options)
- instrument(:fetch_hit, name, options) { }
+ instrument(:fetch_hit, name, options) {}
entry.value
end
def save_block_result_to_cache(name, options)
result = instrument(:generate, name, options) do