From 5d1e8884bd626d1949af79cdb2f2c9ab54ab2028 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 29 Jul 2021 11:38:14 +0200 Subject: [PATCH] Fix MemCacheStore local cache duplication Followup: https://github.com/rails/rails/pull/42833 The previous fix wasn't working in practice because the LocalCache middleware doesn't use `with_local_cache` but directly set a regular `LocalStore` instance in the registry. So instead we redecorate it on every access. It may cause some extra allocations, but since it only happens in 6.1 mode, it's not as much of a concern. --- .../active_support/cache/mem_cache_store.rb | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index ebbc8a5e4d..de0fc8abb8 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -7,6 +7,7 @@ rescue LoadError => e raise e end +require "delegate" require "active_support/core_ext/enumerable" require "active_support/core_ext/array/extract_options" @@ -33,7 +34,7 @@ module ActiveSupport prepend Strategy::LocalCache module DupLocalCache - class LocalStore < Strategy::LocalCache::LocalStore + class DupLocalStore < DelegateClass(Strategy::LocalCache::LocalStore) def write_entry(_key, entry) if entry.is_a?(Entry) entry.dup_value! @@ -42,12 +43,12 @@ module ActiveSupport end def fetch_entry(key) - entry = @data.fetch(key) do + entry = super do new_entry = yield if entry.is_a?(Entry) new_entry.dup_value! end - @data[key] = new_entry + new_entry end entry = entry.dup @@ -59,13 +60,16 @@ module ActiveSupport end end - def with_local_cache - if ActiveSupport::Cache.format_version == 6.1 - use_temporary_local_cache(LocalStore.new) { yield } - else - super + private + def local_cache + if ActiveSupport::Cache.format_version == 6.1 + if local_cache = super + DupLocalStore.new(local_cache) + end + else + super + end end - end end prepend DupLocalCache