diff options
author | Jeremy Daer <jeremydaer@gmail.com> | 2017-06-06 16:39:20 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-06 16:39:20 -0700 |
commit | 2b96d5822bfe407be7589e293f3265c0c7a6726c (patch) | |
tree | f50c2eef76a67707b10be6ce14e856ab95c19cfc /activesupport/lib | |
parent | 0d55b5bb5dfdcf65d1e9a10b567579e3d339c2c9 (diff) | |
download | rails-2b96d5822bfe407be7589e293f3265c0c7a6726c.tar.gz rails-2b96d5822bfe407be7589e293f3265c0c7a6726c.tar.bz2 rails-2b96d5822bfe407be7589e293f3265c0c7a6726c.zip |
Cache: write_multi (#29366)
Rails.cache.write_multi foo: 'bar', baz: 'qux'
Plus faster `fetch_multi` with stores that implement `write_multi_entries`.
Keys that aren't found may be written to the cache store in one shot
instead of separate writes.
The default implementation simply calls `write_entry` for each entry.
Stores may override if they're capable of one-shot bulk writes, like
Redis `MSET`.
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/cache.rb | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index a1093a2e23..fa487060e2 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -373,6 +373,19 @@ module ActiveSupport results end + # Cache Storage API to write multiple values at once. + def write_multi(hash, options = nil) + options = merged_options(options) + + instrument :write_multi, hash, options do |payload| + entries = hash.each_with_object({}) do |(name, value), memo| + memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options))) + end + + write_multi_entries entries, options + end + end + # 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, @@ -397,14 +410,15 @@ module ActiveSupport options = names.extract_options! options = merged_options(options) - results = read_multi(*names, options) - names.each_with_object({}) do |name, memo| - memo[name] = results.fetch(name) do - value = yield name - write(name, value, options) - value + read_multi(*names, options).tap do |results| + writes = {} + + (names - results.keys).each do |name| + results[name] = writes[name] = yield(name) end + + write_multi writes, options end end @@ -521,6 +535,14 @@ module ActiveSupport raise NotImplementedError.new 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 + end + end + # Deletes an entry from the cache implementation. Subclasses must # implement this method. def delete_entry(key, options) |