11

I have two partials which refer to one another. When I calculate nested dependencies in the console likes so (with some debug code outputting which template is being loaded):

finder = ApplicationController.new.lookup_context
ActionView::Digestor.new(name: "posts/show", finder: finder).nested_dependencies

or via the rake task like so:

rake cache_digests:nested_dependencies TEMPLATE=posts/show

I get a short list of initial dependencies, and then this in an infinite loop, until the ruby stack is full:

...
>>>>>>> users/foo
>>>>>>> users/bar
>>>>>>> users/baz
>>>>>>> users/bip
>>>>>>> users/foo
>>>>>>> users/bar
>>>>>>> users/baz
>>>>>>> users/bip
SystemStackError: stack level too deep

(template names changed)

However, when I run the app server and request the template, things run just fine, no infinite loops.

Here are my settings in all of the above cases:

config.action_controller.perform_caching = true
config.cache_store = :file_store, Rails.root.to_s + '/tmp/cache/stuff'
ActionView::Base.cache_template_loading = true

The code indicates that it does have recursive reference protection: https://github.com/rails/rails/blob/v4.1.8/actionview/lib/action_view/digestor.rb#L35

Why is this protection working in the server environment but not in console or the rake task?

(also a github issue https://github.com/rails/rails/issues/18667 )

John Bachir
  • 22,495
  • 29
  • 154
  • 227
  • Rails and the rake task uses two completely different methods. Rails calls `ActionView::Digestor.digest` which calls into `compute_and_store_digest` which has the inifite loop protection. However `nested_dependencies` only calls `DependencyTracker.find_dependencies` recursively without any infinite loop detection. If you check for usages of `nested_dependencies` on github you can see that it is only used from the rake task and nowhere else. So IMHO this is a bug in `nested_dependencies`. – nemesv Jan 24 '15 at 15:16
  • thanks... why is this a comment? – John Bachir Jan 25 '15 at 00:03

1 Answers1

1

Rails and the rake task uses two completely different methods of the ActionView::Digestor.

  • Rails usually calls ActionView::Digestor.digest which calls into compute_and_store_digest which has the infinite loop protection.

  • However nested_dependencies only calls DependencyTracker.find_dependencies recursively without any infinite loop detection.

If you check for usages of nested_dependencies on github you can see that it is only used from the rake task and nowhere else.

So IMHO this is a bug in nested_dependencies.

nemesv
  • 138,284
  • 16
  • 416
  • 359