lib/active_support/cache.rb in activesupport-5.2.0.beta2 vs lib/active_support/cache.rb in activesupport-5.2.0.rc1
- old
+ new
@@ -89,20 +89,15 @@
end
private
def retrieve_cache_key(key)
case
- when key.respond_to?(:cache_key_with_version)
- key.cache_key_with_version
- when key.respond_to?(:cache_key)
- key.cache_key
- when key.is_a?(Hash)
- key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }.to_param
- when key.respond_to?(:to_a)
- key.to_a.collect { |element| retrieve_cache_key(element) }.to_param
- else
- key.to_param
+ when key.respond_to?(:cache_key_with_version) then key.cache_key_with_version
+ when key.respond_to?(:cache_key) then key.cache_key
+ when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param
+ when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a)
+ else key.to_param
end.to_s
end
# Obtains the specified cache store class, given the name of the +store+.
# Raises an error when the store class cannot be found.
@@ -163,10 +158,27 @@
cattr_accessor :logger, instance_writer: true
attr_reader :silence, :options
alias :silence? :silence
+ class << self
+ private
+ def retrieve_pool_options(options)
+ {}.tap do |pool_options|
+ pool_options[:size] = options[:pool_size] if options[:pool_size]
+ pool_options[:timeout] = options[:pool_timeout] if options[:pool_timeout]
+ end
+ end
+
+ def ensure_connection_pool_added!
+ require "connection_pool"
+ rescue LoadError => e
+ $stderr.puts "You don't have connection_pool installed in your application. Please add it to your Gemfile and run bundle install"
+ raise e
+ end
+ end
+
# Creates a new cache. The options will be passed to any write method calls
# except for <tt>:namespace</tt> which can be used to set the global
# namespace for the cache.
def initialize(options = nil)
@options = options ? options.dup : {}
@@ -360,27 +372,15 @@
# Returns a hash mapping the names provided to the values found.
def read_multi(*names)
options = names.extract_options!
options = merged_options(options)
- results = {}
- names.each do |name|
- key = normalize_key(name, options)
- version = normalize_version(name, options)
- entry = read_entry(key, options)
-
- if entry
- if entry.expired?
- delete_entry(key, options)
- elsif entry.mismatched?(version)
- # Skip mismatched versions
- else
- results[name] = entry.value
- end
+ instrument :read_multi, names, options do |payload|
+ read_multi_entries(names, options).tap do |results|
+ payload[:hits] = results.keys
end
end
- results
end
# Cache Storage API to write multiple values at once.
def write_multi(hash, options = nil)
options = merged_options(options)
@@ -417,18 +417,23 @@
raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
options = names.extract_options!
options = merged_options(options)
- read_multi(*names, options).tap do |results|
- writes = {}
+ instrument :read_multi, names, options do |payload|
+ read_multi_entries(names, options).tap do |results|
+ payload[:hits] = results.keys
+ payload[:super_operation] = :fetch_multi
- (names - results.keys).each do |name|
- results[name] = writes[name] = yield(name)
- end
+ writes = {}
- write_multi writes, options
+ (names - results.keys).each do |name|
+ results[name] = writes[name] = yield(name)
+ end
+
+ write_multi writes, options
+ end
end
end
# Writes the value to the cache, with the key.
#
@@ -541,10 +546,32 @@
# this method.
def write_entry(key, entry, options)
raise NotImplementedError.new
end
+ # Reads multiple entries from the cache implementation. Subclasses MAY
+ # implement this method.
+ def read_multi_entries(names, options)
+ results = {}
+ names.each do |name|
+ key = normalize_key(name, options)
+ version = normalize_version(name, options)
+ entry = read_entry(key, options)
+
+ if entry
+ if entry.expired?
+ delete_entry(key, options)
+ elsif entry.mismatched?(version)
+ # Skip mismatched versions
+ else
+ results[name] = entry.value
+ end
+ end
+ end
+ results
+ end
+
# Writes multiple entries to the cache implementation. Subclasses MAY
# implement this method.
def write_multi_entries(hash, options)
hash.each do |key, entry|
write_entry key, entry, options
@@ -567,11 +594,11 @@
end
# Expands and namespaces the cache key. May be overridden by
# cache stores to do additional normalization.
def normalize_key(key, options = nil)
- namespace_key Cache.expand_cache_key(key), options
+ namespace_key expanded_key(key), options
end
# Prefix the key with a namespace string:
#
# namespace_key 'foo', namespace: 'cache'
@@ -592,9 +619,29 @@
if namespace
"#{namespace}:#{key}"
else
key
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)
+ 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) }
+ else
+ key = key.first
+ end
+ when Hash
+ key = key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }
+ end
+
+ key.to_param
end
def normalize_version(key, options = nil)
(options && options[:version].try(:to_param)) || expanded_version(key)
end