Register dependency tracker so nested partials invalidate parent caches#620
Open
rosa wants to merge 1 commit into
Open
Register dependency tracker so nested partials invalidate parent caches#620rosa wants to merge 1 commit into
rosa wants to merge 1 commit into
Conversation
Jbuilder ships `Jbuilder::DependencyTracker` and its railtie requires it, but nothing registers it with `ActionView::DependencyTracker`. Without a registered tracker, `find_dependencies` returns `[]` for every `.jbuilder` template, so the digestor sees no nested-partial dependencies: a `json.cache!` fragment that renders inner partials never mixes those partials' digests into its own cache key. Editing an inner partial then leaves outer fragments serving stale cached JSON until they happen to invalidate for some unrelated reason. ERB doesn't have this problem because Action View registers `ERBTracker`. This is a regression from rails#504, which rewrote the tracker as a standalone class and dropped the `register_tracker :jbuilder` call (and the `ERBTracker` inheritance that used to supply it) without re-adding it. It has shipped unregistered since 2.12.0. Register the tracker from the same `on_load(:action_view)` block that registers the template handler, and declare `supports_view_paths?` so `register_tracker passes` the view paths through to the tracker. Otherwise, Rails wraps it in a lambda that drops them and the tracker's own wildcard (`# Template Dependency: foo/*`) resolution silently returns nothing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
We ran into a caching issue at Basecamp with a template that looked like this:
We changed the
people/_person.json.jbuildertemplate and deployed, yet responses using that template kept returning a stale cached version of the person.We traced this down to nothing registering Jbuilder's dependency tracker with Action View. Its railtie requires it, but nothing registers it with
ActionView::DependencyTracker. Without a registered tracker,find_dependenciesreturns[]for every.jbuildertemplate, so the digestor sees no nested-partial dependencies: ajson.cache!fragment that renders inner partials never mixes those partials' digests into its own cache key. Editing an inner partial then leaves outer fragments serving stale cached JSON until they happen to invalidate for some unrelated reason. ERB doesn't have this problem because Action View registersERBTracker.This is a regression from #504, which rewrote the tracker as a standalone class and dropped the
register_tracker :jbuildercall (and theERBTrackerinheritance that used to supply it) without re-adding it. It has shipped unregistered since 2.12.0.Register the tracker from the same
on_load(:action_view)block that registers the template handler, and declaresupports_view_paths?soregister_tracker passesthe view paths through to the tracker. Otherwise, Rails wraps it in a lambda that drops them and the tracker's own wildcard (# Template Dependency: foo/*) resolution silently returns nothing.