lib/active_support/cache.rb in activesupport-5.2.8.1 vs lib/active_support/cache.rb in activesupport-6.0.0.beta1

- old
+ new

@@ -227,10 +227,18 @@ # # 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 <tt>Cache#write</tt>. # + # Setting <tt>skip_nil: true</tt> will not cache nil result: + # + # cache.fetch('foo') { nil } + # cache.fetch('bar', skip_nil: true) { nil } + # cache.exist?('foo') # => true + # cache.exist?('bar') # => false + # + # # Setting <tt>compress: false</tt> disables compression of the cache entry. # # Setting <tt>:expires_in</tt> will set an expiration time on the cache. # All caches support auto-expiring content after a specified number of # seconds. This value can be specified as an option to the constructor @@ -331,12 +339,13 @@ # Reads data from the cache, using the given key. If there is data in # the cache with the given key, then that data is returned. Otherwise, # +nil+ is returned. # - # Note, if data was written with the <tt>:expires_in<tt> or <tt>:version</tt> options, - # both of these conditions are applied before the data is returned. + # Note, if data was written with the <tt>:expires_in</tt> or + # <tt>:version</tt> options, both of these conditions are applied before + # the data is returned. # # Options are passed to the underlying cache implementation. def read(name, options = nil) options = merged_options(options) key = normalize_key(name, options) @@ -400,40 +409,49 @@ # 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: # # 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" } # + # Options are passed to the underlying cache implementation. For example: + # + # cache.fetch_multi("fizz", expires_in: 5.seconds) do |key| + # "buzz" + # end + # # => {"fizz"=>"buzz"} + # cache.read("fizz") + # # => "buzz" + # sleep(6) + # cache.read("fizz") + # # => nil 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| - read_multi_entries(names, options).tap do |results| - payload[:hits] = results.keys - payload[:super_operation] = :fetch_multi + reads = read_multi_entries(names, options) + writes = {} + ordered = names.each_with_object({}) do |name, hash| + hash[name] = reads.fetch(name) { writes[name] = yield(name) } + end - writes = {} + payload[:hits] = reads.keys + payload[:super_operation] = :fetch_multi - (names - results.keys).each do |name| - results[name] = writes[name] = yield(name) - end + write_multi(writes, options) - write_multi writes, options - end + ordered end end # Writes the value to the cache, with the key. # @@ -585,13 +603,17 @@ end # Merges the default options with ones specific to a method call. def merged_options(call_options) if call_options - options.merge(call_options) + if options.empty? + call_options + else + options.merge(call_options) + end else - options.dup + options end end # Expands and namespaces the cache key. May be overridden by # cache stores to do additional normalization. @@ -632,11 +654,11 @@ case key when Array if key.size > 1 key = key.collect { |element| expanded_key(element) } else - key = key.first + key = expanded_key(key.first) end when Hash key = key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" } end @@ -683,19 +705,19 @@ 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 yield(name) end - write(name, result, options) + write(name, result, options) unless result.nil? && options[:skip_nil] result end end # This class is used to represent cache entries. Cache entries have a value, an optional