diff options
Diffstat (limited to 'actionview')
-rw-r--r-- | actionview/lib/action_view/digestor.rb | 16 | ||||
-rw-r--r-- | actionview/lib/action_view/lookup_context.rb | 16 | ||||
-rw-r--r-- | actionview/test/template/digestor_test.rb | 5 |
3 files changed, 25 insertions, 12 deletions
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 657026fa14..f3c5d6c8df 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -4,13 +4,11 @@ require 'monitor' module ActionView class Digestor - cattr_reader(:cache) - @@cache = Concurrent::Map.new @@digest_monitor = Monitor.new class PerRequestDigestCacheExpiry < Struct.new(:app) # :nodoc: def call(env) - ActionView::Digestor.cache.clear + ActionView::LookupContext::DetailsKey.clear app.call(env) end end @@ -25,12 +23,12 @@ module ActionView def digest(name:, finder:, **options) options.assert_valid_keys(:dependencies, :partial) - cache_key = ([ name, finder.details_key.hash ].compact + Array.wrap(options[:dependencies])).join('.') + cache_key = ([ name ].compact + Array.wrap(options[:dependencies])).join('.') # this is a correctly done double-checked locking idiom # (Concurrent::Map's lookups have volatile semantics) - @@cache[cache_key] || @@digest_monitor.synchronize do - @@cache.fetch(cache_key) do # re-check under lock + finder.digest_cache[cache_key] || @@digest_monitor.synchronize do + finder.digest_cache.fetch(cache_key) do # re-check under lock compute_and_store_digest(cache_key, name, finder, options) end end @@ -42,16 +40,16 @@ module ActionView # Prevent re-entry or else recursive templates will blow the stack. # There is no need to worry about other threads seeing the +false+ value, # as they will then have to wait for this thread to let go of the @@digest_monitor lock. - pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion + pre_stored = finder.digest_cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion PartialDigestor else Digestor end - @@cache[cache_key] = stored_digest = klass.new(name, finder, options).digest + finder.digest_cache[cache_key] = stored_digest = klass.new(name, finder, options).digest ensure # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache - @@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest + finder.digest_cache.delete_pair(cache_key, false) if pre_stored && !stored_digest end end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index 2a1f4378f5..86afedaa2d 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -69,6 +69,18 @@ module ActionView def self.clear @details_keys.clear end + + def self.empty?; @details_keys.empty?; end + + def self.digest_caches + @details_keys.values.map(&:digest_cache) + end + + attr_reader :digest_cache + + def initialize + @digest_cache = Concurrent::Map.new + end end # Add caching behavior on top of Details. @@ -194,6 +206,10 @@ module ActionView self.view_paths = view_paths end + def digest_cache + details_key.digest_cache + end + def initialize_details(target, details) registered_details.each do |k| target[k] = details[k] || Accessors::DEFAULT_PROCS[k].call diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index e50caac6d8..9ff5f7126b 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -33,7 +33,6 @@ class TemplateDigestorTest < ActionView::TestCase def teardown Dir.chdir @cwd FileUtils.rm_r @tmp_dir - ActionView::Digestor.cache.clear end def test_top_level_change_reflected @@ -301,12 +300,12 @@ class TemplateDigestorTest < ActionView::TestCase def assert_digest_difference(template_name, options = {}) previous_digest = digest(template_name, options) - ActionView::Digestor.cache.clear + finder.digest_cache.clear yield assert_not_equal previous_digest, digest(template_name, options), "digest didn't change" - ActionView::Digestor.cache.clear + finder.digest_cache.clear end def digest(template_name, options = {}) |