Class: ActionView::Digestor

Inherits:
Object
  • Object
show all
Defined in:
lib/action_view/digestor.rb

Defined Under Namespace

Modules: PerExecutionDigestCacheExpiry Classes: Injected, Missing, Node, NullLogger, Partial

Constant Summary collapse

@@digest_mutex =
Mutex.new

Class Method Summary collapse

Class Method Details

.digest(name:, finder:, dependencies: []) ⇒ Object

Supported options:

  • name - Template name

  • finder - An instance of ActionView::LookupContext

  • dependencies - An array of dependent views



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/action_view/digestor.rb', line 23

def digest(name:, finder:, dependencies: [])
  dependencies ||= []
  cache_key = [ name, finder.rendered_format, dependencies ].flatten.compact.join(".")

  # this is a correctly done double-checked locking idiom
  # (Concurrent::Map's lookups have volatile semantics)
  finder.digest_cache[cache_key] || @@digest_mutex.synchronize do
    finder.digest_cache.fetch(cache_key) do # re-check under lock
      partial = name.include?("/_")
      root = tree(name, finder, partial)
      dependencies.each do |injected_dep|
        root.children << Injected.new(injected_dep, nil, nil)
      end
      finder.digest_cache[cache_key] = root.digest(finder)
    end
  end
end

.loggerObject



41
42
43
# File 'lib/action_view/digestor.rb', line 41

def logger
  ActionView::Base.logger || NullLogger
end

.tree(name, finder, partial = false, seen = {}) ⇒ Object

Create a dependency tree for template named name.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/action_view/digestor.rb', line 46

def tree(name, finder, partial = false, seen = {})
  logical_name = name.gsub(%r|/_|, "/")

  if template = find_template(finder, logical_name, [], partial, [])
    finder.rendered_format ||= template.formats.first

    if node = seen[template.identifier] # handle cycles in the tree
      node
    else
      node = seen[template.identifier] = Node.create(name, logical_name, template, partial)

      deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
      deps.uniq { |n| n.gsub(%r|/_|, "/") }.each do |dep_file|
        node.children << tree(dep_file, finder, true, seen)
      end
      node
    end
  else
    unless name.include?("#") # Dynamic template partial names can never be tracked
      logger.error "  Couldn't find template for digesting: #{name}"
    end

    seen[name] ||= Missing.new(name, logical_name, nil)
  end
end