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