aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorGabriel Sobrinho <gabriel.sobrinho@gmail.com>2018-02-06 12:16:42 -0200
committerJeremy Daer <jeremydaer@gmail.com>2018-02-23 12:53:01 -0800
commit1077ae96b34b5a1dfbf10ee0c40b1ceb1eb6b30b (patch)
tree49a011bf2eb2f2d302841249178887e317fe06b3 /activesupport
parent5ecbeda0e225e4961977b5c516088cf12d92319f (diff)
downloadrails-1077ae96b34b5a1dfbf10ee0c40b1ceb1eb6b30b.tar.gz
rails-1077ae96b34b5a1dfbf10ee0c40b1ceb1eb6b30b.tar.bz2
rails-1077ae96b34b5a1dfbf10ee0c40b1ceb1eb6b30b.zip
Caching: MemCache and Redis stores use local cache for multi-reads
Fixes #31909. Closes #31911.
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md5
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb17
-rw-r--r--activesupport/test/cache/behaviors/local_cache_behavior.rb10
3 files changed, 32 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 73896be453..db53c151ea 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,5 +1,10 @@
## Rails 6.0.0.alpha (Unreleased) ##
+* Caching: MemCache and Redis `read_multi` and `fetch_multi` speedup.
+ Read from the local in-memory cache before consulting the backend.
+
+ *Gabriel Sobrinho*
+
* Return all mappings for a timezone identifier in `country_zones`
Some timezones like `Europe/London` have multiple mappings in
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index aaa9638fa8..e17308f83e 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -54,6 +54,10 @@ module ActiveSupport
@data[key]
end
+ def read_multi_entries(keys, options)
+ Hash[keys.map { |name| [name, read_entry(name, options)] }.keep_if { |_name, value| value }]
+ end
+
def write_entry(key, value, options)
@data[key] = value
true
@@ -116,6 +120,19 @@ module ActiveSupport
end
end
+ def read_multi_entries(keys, options)
+ return super unless local_cache
+
+ local_entries = local_cache.read_multi_entries(keys, options)
+ missed_keys = keys - local_entries.keys
+
+ if missed_keys.any?
+ local_entries.merge!(super(missed_keys, options))
+ else
+ local_entries
+ end
+ end
+
def write_entry(key, entry, options)
if options[:unless_exist]
local_cache.delete_entry(key, options) if local_cache
diff --git a/activesupport/test/cache/behaviors/local_cache_behavior.rb b/activesupport/test/cache/behaviors/local_cache_behavior.rb
index f7302df4c8..363f2d1084 100644
--- a/activesupport/test/cache/behaviors/local_cache_behavior.rb
+++ b/activesupport/test/cache/behaviors/local_cache_behavior.rb
@@ -119,6 +119,16 @@ module LocalCacheBehavior
end
end
+ def test_local_cache_of_fetch_multi
+ @cache.with_local_cache do
+ @cache.fetch_multi("foo", "bar") { |_key| true }
+ @peek.delete("foo")
+ @peek.delete("bar")
+ assert_equal true, @cache.read("foo")
+ assert_equal true, @cache.read("bar")
+ end
+ end
+
def test_middleware
app = lambda { |env|
result = @cache.write("foo", "bar")