Class: Rabl::Digestor
- Inherits:
-
ActionView::Digestor
- Object
- ActionView::Digestor
- Rabl::Digestor
- Defined in:
- lib/rabl/digestor.rb
Class Method Summary collapse
Class Method Details
.digest(name, format, finder, options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/rabl/digestor.rb', line 6 def self.digest(name:, finder:, **) .assert_valid_keys(:dependencies, :partial) cache_key = ([ name ].compact + Array.wrap([:dependencies])).join('.') # this is a correctly done double-checked locking idiom # (Concurrent::Map's lookups have volatile semantics) finder.digest_cache[cache_key] || @@digest_monitor.synchronize do finder.digest_cache.fetch(cache_key) do # re-check under lock begin # 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 = finder.digest_cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion finder.digest_cache[cache_key] = stored_digest = Digestor.new(name, finder, ).digest ensure # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache finder.digest_cache.delete_pair(cache_key, false) if pre_stored && !stored_digest end end end end |