Skip to content

Commit

Permalink
Merge pull request #11452 from dasch/dasch/details-in-digestor-cache-key
Browse files Browse the repository at this point in the history
Bust the template digest cache key when details are changed
  • Loading branch information
José Valim committed Sep 20, 2013
2 parents 3408857 + 77e79ec commit eb1cacf
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
6 changes: 6 additions & 0 deletions actionview/CHANGELOG.md
Expand Up @@ -13,6 +13,12 @@


*Josh Lauer*, *Justin Ridgewell* *Josh Lauer*, *Justin Ridgewell*


* Fixed a bug where the lookup details were not being taken into account
when caching the digest of a template - changes to the details now
cause a different cache key to be used.

*Daniel Schierbeck*

* Added an `extname` hash option for `javascript_include_tag` method. * Added an `extname` hash option for `javascript_include_tag` method.


Before: Before:
Expand Down
5 changes: 4 additions & 1 deletion actionview/lib/action_view/digestor.rb
Expand Up @@ -10,7 +10,10 @@ class Digestor


class << self class << self
def digest(name, format, finder, options = {}) def digest(name, format, finder, options = {})
cache_key = ([name, format] + Array.wrap(options[:dependencies])).join('.') details_key = finder.details_key.hash
dependencies = Array.wrap(options[:dependencies])
cache_key = ([name, details_key, format] + dependencies).join('.')

# this is a correctly done double-checked locking idiom # this is a correctly done double-checked locking idiom
# (ThreadSafe::Cache's lookups have volatile semantics) # (ThreadSafe::Cache's lookups have volatile semantics)
@@cache[cache_key] || @@digest_monitor.synchronize do @@cache[cache_key] || @@digest_monitor.synchronize do
Expand Down
30 changes: 29 additions & 1 deletion actionview/test/template/digestor_test.rb
Expand Up @@ -15,6 +15,16 @@ def initialize(template_path)
class FixtureFinder class FixtureFinder
FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor" FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor"


attr_reader :details

def initialize
@details = {}
end

def details_key
details.hash
end

def find(logical_name, keys, partial, options) def find(logical_name, keys, partial, options)
FixtureTemplate.new("digestor/#{partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name}.#{options[:formats].first}.erb") FixtureTemplate.new("digestor/#{partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name}.#{options[:formats].first}.erb")
end end
Expand Down Expand Up @@ -140,6 +150,20 @@ def test_collection_derived_from_record_dependency
end end
end end


def test_details_are_included_in_cache_key
# Cache the template digest.
old_digest = digest("events/_event")

# Change the template; the cached digest remains unchanged.
change_template("events/_event")

# The details are changed, so a new cache key is generated.
finder.details[:foo] = "bar"

# The cache is busted.
assert_not_equal old_digest, digest("events/_event")
end

def test_extra_whitespace_in_render_partial def test_extra_whitespace_in_render_partial
assert_digest_difference("messages/edit") do assert_digest_difference("messages/edit") do
change_template("messages/_form") change_template("messages/_form")
Expand Down Expand Up @@ -220,7 +244,11 @@ def assert_digest_difference(template_name, persistent = false)
end end


def digest(template_name, options={}) def digest(template_name, options={})
ActionView::Digestor.digest(template_name, :html, FixtureFinder.new, options) ActionView::Digestor.digest(template_name, :html, finder, options)
end

def finder
@finder ||= FixtureFinder.new
end end


def change_template(template_name) def change_template(template_name)
Expand Down

0 comments on commit eb1cacf

Please sign in to comment.