Problem/Motivation
Just because Views depends on a certain config existing doesn't automatically mean that the rendered View depends on the data that's in that config, and so doesn't need to be cleared when that config is updated. Furthermore, if there's a certain kind of config dependency where the contents do matter, then that should get reflected by the appropriate plugin somewhere in the render array that the plugin generates, and the plugin should set the corresponding cache tags there, and those will bubble up. So because of that bubbling, there's no need to automatically add them for every dependency.
Views already bubbles up cache tags of rendered entities correctly.
But what it does not yet do, is:
- … associating those bubbled cache tags with its output cache items
- In HEAD, any Views output cache item only contains:
- the view's own cache tag (e.g.
view:frontpage) - and the listed entity types' list cache tags (e.g.
node_list)
… yet the item that is being cached actually also contains the cache tags for rendered node 1:
node:1, user:5, term:3, node_viewand so on. If the output cache item does not get those cache tags as well, it will continue to be used, even after node 1, user 5 or term 3 have been modified.
- the view's own cache tag (e.g.
- … setting its own cache tags on the render array
- Views output caching sets its own cache tags on the output cache item (the aforementioned
view:frontpageandnode_list), which is great. But it should also set those cache tags on the render array. Because that doesn't happen right now, changing the view, or creating new entities of the listed entity type doesn't cause a render cached View to be invalidated.
Proposed resolution
TBD
Remaining tasks
Consensus on what needs to happen.- Improve the tests that were added in #24/#25:
- they need to be generic, and shouldn't live in existing tests; we should have a single
ViewsCacheTagsTestthat tests all permutations (and then they can subclassPageCacheBase, which is probably a better fit anyway). - they should also verify the cache tags on the Views output cache items.
- they need to be generic, and shouldn't live in existing tests; we should have a single
- Field views don't actually set the right cache tags yet, this might be related to #2350551: Views fields that have attached assets are lost when Views output caching is enabled. #24/#25 added a
@todoin the test coverage for that. - Review
User interface changes
None.
API changes
None.
Original report by @Wim Leers
E.g. if a view filters to article nodes, it should depend on the article node type config entity, and associate its cache tag, so that if the article node type is changed, that the render cached view is also invalidated.
| Comment | File | Size | Author |
|---|---|---|---|
| #111 | interdiff.txt | 6.41 KB | dawehner |
| #111 | 2381217-111.patch | 51.15 KB | dawehner |
| #105 | interdiff.txt | 12.85 KB | wim leers |
| #105 | 2381217-105.patch | 51.8 KB | wim leers |
| #104 | interdiff.txt | 1.89 KB | wim leers |
Comments
Comment #1
dawehnerDo I understand the issue right: We should add config dependencies as well as fetch its cache tags?
Given that we have a class for that already:
\Drupal\views\Plugin\views\filter\Bundlewe could start here with implementing
DependentPluginInterfaceIn general I consider #2372855: Add content & config entity dependencies to views more as a meta issue?
Comment #2
wim leersClarifying the issue title.
#2372855: Add content & config entity dependencies to views is about adding the config/content entity dependencies to views config entities.
This issue is about also applying those dependencies to render arrays, and hence setting the associated cache tags.
Comment #3
wim leersComment #4
wim leers#2372855: Add content & config entity dependencies to views landed, this is now only blocked on #2342651: Cache tags for *all* config entities.
Comment #5
berdirAre we actually blocked on #2342651: Cache tags for *all* config entities? config entities have cache tags, the other issue is "just" about ensuring they are used everywhere where they need to be?
So you could almost argue that this issue is part of that ;)
Comment #6
wim leersI think you're right. I think I might've blocked this issue on that one because right now we don't have guarantees that e.g.
NodeTypeconfig entities are invalidated when necessary. But as you say, this is in fact part of that issue.From the IS:
The part is already happening, that was done in #2372855: Add content & config entity dependencies to views.
It's the part that's still missing. Now investigating.
Comment #7
wim leersAgain taking this as an example:
Having worked on #2372855: Add content & config entity dependencies to views, I'm no longer sure that this is actually true. At least, I'm not sure anymore about this particular example. I think the quoted statement (from the IS) is wrong in multiple ways:
node.type.articlein this example), not on the associated view mode (see\Drupal\views\Plugin\views\filter\Bundle::calculateDependencies())core.entity_view_mode.node.teaserin this example). Entity View Mode config entities represent the different view modes that are available for a certain entity type. But these are NOT the same as the Entity View Display config entities, which represent the configuration of a given view mode for a certain bundle. (I learned this the hard way in that other issue.) Given that a View is per-entity type, is configured at the entity type level, and can at best filter to a certain bundle, it is only natural that a view only depends on an Entity View Mode, and not on an Entity View Display.A direct consequence is that a view cannot actually associate the cache tag of the Entity View Displays that are used by the entities it renders; only the rendered entities themselves can associate those cache tags. But this is actually already what the view builder cache tags are being used for, which already are associated with the rendered entities; we should look into removing those in favor of Entity View Display config entities' cache tags).
Hence, doing what the IS said is impossible and to some extent even nonsensical.
I also always thought that all config/content dependencies for a view should also have the corresponding cache tags set on the rendered view. I no longer think that's actually the case. For example, a Views
Pagedisplay can optionally have a menu link associated with it. When a certain view uses that, a content dependency on the associatedmenu_link_contentdependency appears. But does it make sense to associate a menu link's cache tag with a View? No, not at all, because a rendered view neither contains the menu link in question, nor is a rendered view going to change if that menu link changes. It's a dependency, but it's completely irrelevant to the rendered view.Conclusion
I think the goal of this issue — — is wrong. I might've missed something though, so please prove me wrong.
However…
…the spirit of this issue really is "make sure View config entities' cache tags are bubbled up" (including test coverage). I tested this, and it's very, very broken — but then again, Views only received cache tag support in a plugin, it was never designed or updated to support cache tags from the ground up.
So I propose to rename this issue to just and fix the current brokenness:
view:<view ID>and<entity type>:listcache tags only exist on Views output cache itemsview:frontpagecache tag), and they are only ever set if Views' caching is enabled.This should cause a fair number of test failures.
Comment #8
wim leersAnd since this blocks #2342651: Cache tags for *all* config entities, which was triaged critical, marking this as critical also.
Comment #9
wim leersComment #10
dawehnerThat is a little bit odd ... we should not just copy the logic ... we could make that a method of, maybe the view executable and reuse it in the result cache? ... Note: This kind of information seems all be possible to determine on view safe time, so should we move this all onto
$this->storage->getCacheTags?Comment #11
yched commentedA couple thoughts, possibly completely irrelevant, so forgive me if I'm just adding noise :-/
- EntityViewDisplay::postSave() clears the render cache for the whole entity type when the EVD for any bundle + view mode gets updated (a bit harsh, but doesn't happen that often, and also, not sure if there's any way we can be more granular ?)
That should take care of views that display fully rendered entities ?
- Views that display individual fields (like admin/content) are currently out of the regular "entity view" flow completely, so I guess they skip any render cache as well ?
#1867518: Leverage entityDisplay to provide fast rendering for fields has a plan to move "render a row = render a (bunch of) entity(es) and cherry-pick the rendered fields from the resulting render array", but I guess that wouldn't help the render cache stores rendered HTML, and we can't cherry-pick in there, right ?
Comment #12
wim leersAbsolutely. This is hacky, proof-of-concept code.
This is interesting. But I think it may be semantically wrong… because e.g. if a view's result cache should be invalidated whenever the list of nodes is changed, that only is relevant for the *result cache* (well, also the output cache), but not for the *view itself*. Consequently, if
View::getCacheTags()would return the list cache tags of the entity types that view lists, then every node listing would be invalidated when that view was changed. So if a rarely used node view is modified, all node views' caches would be invalidated. I don't think we want that.But what we could do, is still determine this at save time, but instead expose it in a
getExecutedViewCacheTags()method (whatever the name would be).That being said, I'd rather focus on fixing cache tags in this issue rather than also making determining the right cache entity list tags faster.
This reminds me of #2318377: Determine whether a view is cacheable and its required contexts, store this i/t config entity, where we did all of the work to save the required cache contexts to the config entity, but then aren't actually using that information yet! (And we didn't add tests :() But that's out of scope for this issue; this issue only deals with cache tags.
Comment #13
wim leersI figured I'd actually try to implement your suggestions already. I encountered a few things:
ViewExecutable, then it of course must be public.Comment #14
wim leersOh, sorry, I missed #11!
Correct. Note that #7 was trying to talk about the abstract problem, but used concrete examples (and the one you give in particular because that's the key example listed in the IS).
Indeed, but with some nuance! The fields are render cacheable. If they use field formatters — which they do AFAIK — they also have the appropriate cache tags. But they do *not* use render caching individually, as in on a per-field basis, because entities are already render cacheable. It's up to Views to do render caching. And Views actually does that, with its "output cache".
Ohhhhh! It wouldn't help this issue AFAICT, but I think that'd be very worthwhile to do that.
Comment #17
wim leersShould be green now. But the fact that we have so few failures shows how little test coverage we have here.
Comment #18
effulgentsia commentedI agree with #7, and seems like everyone else here does as well, so tagging for an IS update to remove that erroneous example.
As Wim explained, just because Views depends on a certain config existing doesn't automatically mean that the rendered View depends on the data that's in that config, and so doesn't need to be cleared when that config is updated. Furthermore, if there's a certain kind of config dependency where the contents do matter, then that should get reflected by the appropriate plugin somewhere in the render array that the plugin generates, and the plugin should set the corresponding cache tags there, and those will bubble up. So because of that bubbling, there's no need to automatically add them for every dependency.
However, I wonder what should happen when a dependent config gets deleted. e.g., a View is configured to filter on a certain node type, and then someone deletes that node type. Does the CMI dependency management system prevent the deletion entirely or does it invoke hooks for the View to respond to the deletion? If the latter, then the response should clear the cache, but that probably is already covered by the fact that such a response would necessarily involve resaving the View, thereby clearing the View's cache tag.
I also agree with the bottom of #12: that where the dependency information will more likely come into play is for determining cache granularity, since unlike tags, there's no bubbling mechanism for granularity. But that's out of scope for this issue.
Comment #19
berdirCMI dependencies do have a system for this, but right now, that is only invoked when a module is uninstalled.
I'd love to integrate that into a standard config entity delete form as well. I don't think we can force it on API level, at least not in D8 anymore, but if we'd have it for forms (Where the problem is that we are missing a common delete confirm form base class..)
Comment #20
wim leers#18:
Exactly!
AFAIK: yes. But, as Berdir says, it's only used for uninstall.
#19:
Yes!
Comment #21
wim leersDiscussed with damiankloip and Berdir; we decided to keep this issue focused on the output cache only, not the results cache. Will need to reroll to remove the changes in that area.
Comment #22
wim leersAs per #21: removed the changes to Views' results cache logic.
Comment #23
wim leersIS updated since we have consensus about the new scope.
Comment #24
wim leersHere's test coverage.
Two things I dislike about the test coverage:
FrontPageTestwith test coverage for entity views, andGlossaryTestfor field views.Would be great to get some feedback. I'll be AFK the next 2 weeks, so feel free to push this forward in the mean time.
Comment #25
wim leersIgnore #24, this is the right patch.
Comment #27
dawehner... the exception message is bad ... $this->query is the query plugin, so its not before the query was built. Just name it '... may only be called after the query was initialized' or just initialize it here.
Comment #28
wim leersUpdated IS to indicate the remaining tasks.
Comment #29
wim leersComment #30
effulgentsia commentedDiscussed this with the core maintainers, and they agreed that Views output and parent element (e.g., page) caches not getting cleared when they need to be is critical.
Comment #31
dawehnerSo yeah, let's just to a quick $this->initQuery() and be done with it.
Comment #32
wim leersDone.
Comment #33
damiankloip commentedThis seems a bit hacky tbh. This should be on the display not the view exectuable. It's ideally not this class that cares about what the output from the display is. As signified with the is_array() check, this does not make sense for all displays
Why are we moving this to the view executable? This is something that is specific to the cache plugin IMO? This makes it much harder for people to override it if needed. If we want to keep this for convenience, delegate to the cache plugin.
Ha
Comment #34
berdirWhat @damiankloip wrote.
Moving this away from the cache plugins makes it impossible to customize?
We started experimenting with a custom tag cache plugin, that adds a configurable cache tag, instead of the default list cache tags, so that we can do more targeted cache invalidations.
This would be impossible with this change? So we still need to delegate it, and ensure that we always have a cache plugin active, even if that defaults to not to cache.
Comment #35
wim leersWith #2350551: Views fields that have attached assets are lost when Views output caching is enabled committed, I can now continue here. Expect an update later today or tomorrow.
Comment #36
wim leersFirst, a straight reroll of #32. #2040135: Caches dependent on simple config are only invalidated on form submissions conflicted with this in several places.
This is going to fail tests.
Comment #37
wim leersNow with tests passing.
Next: address #33 + #34. Then: fix the @todo mentioned in #24 & #35.
Comment #38
wim leersThis is blocked on me addressing the feedback, not blocked on review.
Comment #41
webchickSorry, just doing some house-cleaning. Since D8 cacheability is a subset of Performance, adding the more common tag as well.
Comment #42
webchickAlso removing what looks like obsolete "blocked on" information from the issue summary, given #6.
Comment #43
dawehnerHonestly I would better like this logic in a different place, like the CachePluginBase. Expanding the amount of code in ViewExecutable is not the best solution IMHO.
Ha, damian mentioned the same point damian++ berdir++
* rerolled
* fixed the failure
* moved the logic back into the cachepluginbase.
Comment #45
dawehnerdawehner-- rebase destroyer.
Comment #46
berdirTest looks pretty good, is it worth expanding it to explicitly check invalidation by updating one of the nodes checking that we e.g. get the new node title in the output? Should we enable the views cache as well or is this already the case? That might be useful to verify when we also change the created timestamp of that node, so that the first one shows up on the first page...
It currently also hardcodes node id's, which is something we try to avoid, because a different mysql configuration could result in different ID's.
You could specify the nid explicitly when creating, together with enforceIsNew()?
This issue is actually fixed now...
Is this a left-over of having the method on the view or is there a reason we're not simply calling getCacheTags() here?
Temporary debugging help or do you mean to keep this enabled?
I'd say that is an implementation detail that should not be mentioned here?
We're already working on a cache plugin that does *not* add the list cache tag, but a custom cache tag that can be entered by the user, just waiting for this issue to land to start using it.
Comment #47
berdir2. is supposed to be on the @todo right above the sort() call..
Comment #48
dawehnerNote: VIews sets the cache tags, and the page cache entry will use it.
Please have a look whether
Total fair point.
Comment #49
dawehnerUps.
Comment #52
dawehnerLet's not remove the sort.
Comment #53
jibranComment #54
fabianx commentedShould this not use:
Cache::mergeTags instead?
Comment #55
dawehnerI'm not sure whether this implementation is right, its tricky to find out when we actually render something which looks like an entity, and is not just a fake.
Comment #56
berdirWe're experimenting with a custom cache tag views cache plugin, that allows to define a custom cache tag per view instead of the default list cache tag.
Some feedback based on that..
a) It actually works, including page cache :)
b) The new AssertPageCacheTagsTrait is interesting, but why is that different from PageCacheTagsTestBase and specifically, why doesn't it allow to test for page cache hit/miss like that one? We are implicitly checking that the page is updated when something changes, but we never check if it actually was a page cache hit before.
c) What @jibran said in #53, we first tried with a view with fields, but then you actually don't have the node specific cache tags in there. Oh, if I understand @dawehner correctly, this should now be fixed with that. Crossposted with him. We also need a test for a view with fields then?
Comment #58
dawehnerJust fixed the failure.
Comment #59
wim leers#43
Wrong, because:
#55
This is necessary for field views, right?
#2342045: Standard views base fields need to use same rendering as Field UI fields, for formatting, access checking, and translation consistency should ensure every field has the correct cache tags. (Because it reuses the same field formatters as we use for "regular" entity rendering.)
This, in turn, ensures that the cache tag of the entity owning that field is also associated. That makes sense.
Finally, I want to call out that #1867518: Leverage entityDisplay to provide fast rendering for fields is closely related to all this too (it's already marked as a related issue of #2342045).
#56
b)
assertPageCacheTags()always does 2 requests, the first must be a miss, the second must be a hit, and both must have the expected cache tags. Updating its docs.c) Indeed, @dawehner fixed that.
Finally, having tested this patch, this part of the issue title was (IIRC) fixed in my patch, but now is broken again: .
STR:
frontpage:page_1:output:<hash>. Look at its cache tags.Expected: the term's cache tag, the author's cache tag, the text format's cache tag are all present.
Actual: they're missing.
(Basically:
frontpage:page_1:output:<hash>'s cache tags must be a superset ofentity_view:node:1:teaser:*'s, but they're not!)In this reroll:
AssertPageCacheTagsTrait. (Addresses #56b.)\Drupal\views\Tests\ViewTestBase::assertViewsCacheTags()FrontPageTest, to demonstrate the problem with the output cache reported above. I'm also checking the results cache, because there too we want to know for sure that the right cache tags are present. And to verify it works correctly, I'm also rendering the frontpage view before any nodes are created, to check the correct cache tags are present in that case (they are!). BUT… in doing so, I'm running into bizarre problems:node_listcache tag is invalidated 15 times, the Views result & output cache items (which has thenode_listcache tag, as it should) continues to indicate that there are no nodes to list on the frontpage!? Since the cache tags were invalidated correctly, that leaves only one possible conclusion for me: static caching somewhere in Views. But if that's the case, then why doesn't\Drupal\views\Tests\Plugin\CacheTagTest::testTagCaching()suffer from that?Comment #61
wim leers(The two test failures are intentional, they demonstrate the problems/bugs in patch #58. But there would be more failing tests, if it weren't for the Views-static-caching problems I ran into while writing the tests. See bottom of #59.)
Comment #62
dawehnerDid some quick debugging and it turned out, the results key of the cache on the actual site, and on the simpletest is different.
As it turns out, the wrong display ID is simply used in the test.
PS: #2442769: Views result cache ignores query arguments.
Comment #63
dawehnerLet's upload an actual patch.
Comment #65
dawehnerThis at least solves the most obvious problem, we store the wrong cache tags.
Now the page cache doesn't work, because we have a notice on the page, triggered by #2378815: DisplayPluginBase::elementPreRender() and View::preRenderViewElement() are called even when the Views output cache is being used, causing notice so I leveled up that one.
Comment #67
dawehnerFixed the failures as well as worked on some general test coverage.
Comment #71
fabianx commentedThis should fix the test failure.
Comment #73
dawehnerSure, ... working on it currently to provide more test coverage.
Comment #74
dawehnerAdded some test coverage for the pager to ensure the right entries appear.
Comment #75
fabianx commented#74, @Wim: Do we need more test coverage or is this ready for final review?
Comment #76
wim leersFirst, a thorough review of the current patch, including the test coverage. Conclusion: this looks great!
Doing this in my next comment.
Indentation. Fixed.
'rendered' is already in there. Fixed.
This is caching a rendered render array. Hence it really is render caching. And thus should get the 'rendered' cache tag.
If you're hesitant about that, then look at this argument: the Views output cache contains rendered render arrays. This means that the theme is already involved, and its templates have run. Theme settings use the
'rendered'cache tag. Therefore, whenever the theme settings are changed, all things affected by the theme must change, which includes all cached rendered render arrays, which includes those in the Views output cache.So the results key was wrong before… interesting. This also means there was no test coverage for this aspect of the results cache. And now there is — awesome!
This is now public because
ViewExecutable::getCacheTags()calls it.This says "WithPager", but it doesn't configure a pager anywhere… meaning that it's really the same test as above.
… but then I realized you were setting
page_1as the display here, but thetestTimeResultCaching()case uses the default display.So this actually makes sense. I made minor modifications to that other test case to clarify the difference.
… etc.
We always use
Cache::mergeTags()to merge cache tags. Fixed.These were missing some docs and are pretty tricky to follow initially. Made some minor improvements that IMO make it easier to understand these tests.
Comment #77
dawehnerwell, previously it just relied on the request, now it relies on the actual views API.
The additional changes from @Wim Leers are looking great!
Good catch ... this was just a c&p from above.
Comment #79
dawehnerFix the failures.
Comment #80
wim leersAddressed #76.1.
(The interdiff is relative to #76.)
Comment #81
wim leersStupid c/p error.
Comment #83
dawehnerMh, I hate that we extend the test coverage of the frontpage, even technically we should expand the test coverage of
RenderCacheIntegrationTestComment #84
fabianx commentedCould we expand the test coverage of both, please?
Yes its redundant, but its also two different scenarios / paths, that could break independently.
At least in my D7 render caching development that is the experience I got ...
Comment #85
wim leersAlright, done.
Comment #86
wim leersI forgot to test
FrontPageTestagain — I broke it in the process due to the necessary changes I made toAssertViewsCacheTagsTrait::assertViewsCacheTags().Fixed.
Comment #91
wim leersComment #93
wim leersWhile I was rolling this patch, #2445761: Add a X-Drupal-Cache-Contexts header to aid in debugging and testing got committed, which caused this conflict.
Comment #94
dawehnerI would be kinda great if the test code could explain WHY this is needed.
Comment #96
wim leers#94: it was just a hunch. Compare #86 with #93 and you'll see that we have the exact same failures. So my hunch was wrong. :(
The thing is: this is green on my local D8. So… I really don't know what else to do. #91 can be reverted for sure, but I'm out of ideas. The only thing I can think of is to add a shitton of debug output and then analyze it again.
Hopefully you have an idea why Testbot has different results than a local D8?
Comment #97
dawehnerHave you used run-tests.sh? I had these kind of failures just on run-tests.sh, but not in the UI, before for this issue.
Comment #98
berdirNot sure, the missing cache tag seems to be 'rendered', and looking at the assert that I think is triggering this (there are multiple nested calls, all reported as the same line, so a bit hard to see), then it is there in the actual cache tags, but not the expected ones. I'm not sure why, you seem to add merge it into the expected ones?
Not that related, but maybe we can find a better way to display those assertions, and display only those that are different? (e.g. array_diff() in both directions, with no unexpected cache tags found + all expected cache tags found messages? It's always hard to find the one that's different.
Comment #99
fabianx commentedYeah, Wim use the UI to run tests ;).
Seriously this is again the same problem that 'rendered' is somehow not added for the cli that dawehner ran into earlier.
Comment #100
wim leersI actually am running the tests using the UI. (I almost never use
run-tests.sh.)And yes, the "missing" cache tag is
'rendered'. It's not actually missing though: it is set despite us expecting it to NOT be set! It's happening for this assertion:i.e. when we're inspecting the render array. A render array never receives the
renderedcache tag unless it contains something that already was render cached. That's also why I tried #91.Comment #101
fabianx commentedNot sure, but maybe:
core/lib/Drupal/Core/Datetime/Entity/DateFormat.php: return ['rendered'];
with the list_cache_tags being still set to rendered?
Edit or alternatively:
core/lib/Drupal/Core/Theme/ThemeSettings.php: return ['rendered'];
?
Comment #102
dawehner@wim
So running via run-tests.sh did not fail? This worked for me.
Comment #103
wim leersReproduced now. I've got a fix in the works, but can't finish it today. Expect it early tomorrow.
Comment #104
wim leersFirst, a small reroll that allows one to reproduce it even when using the UI test runner. The root cause for the difference in test results is that
run-tests.shalways mocks a GET request, whereas the UI test runner doesn't.Next up: a fix.
Comment #105
wim leersNow that we're able to reproduce the problem reliably, the real problem becomes obvious: the annoying presence of the
'rendered'cache tag in case of a render cache HIT.If I render my render array, and a child of that just happens to be render cacheable, then the first time I render my render array, it'll have the expected set of cache tags, but the second time, it'll be the expected set plus the
'rendered'cache tag (due to the first time causing a render cache MISS plus a write so the second time it'll be a HIT).This is a consequence that wasn't taken into account initially, and can easily be avoided: only set the
'rendered'cache tag on the render cache item, not on the render array that's about to be render cached!This interdiff does exactly that. But it also ensures that we don't lose any test coverage; it in fact provides a better test coverage than HEAD: it verifies that render cache items indeed have the
'rendered'cache tag.Comment #107
fabianx commentedCan we fix those two, too, while cleaning up 'rendered' to keep those changes together?
core/lib/Drupal/Core/Datetime/Entity/DateFormat.php: return ['rendered'];
core/lib/Drupal/Core/Theme/ThemeSettings.php: return ['rendered'];
Thanks!
--
It's green - will review later - if no one beats me to it.
Comment #108
wim leers#107: uh, no, those are intentional. They're saying "hey, use the 'rendered' cache tag for this config (entity)!"
Comment #109
fabianx commentedRTBC, this looks great now!
Thanks!
Comment #111
dawehnerI fear the interdiff is not 100% correct.
For the sake of fixability I think we should add the debug statements in there.
Comment #112
wim leersDiffing #105 and #111 locally shows sane changes only; the #111 interdiff is indeed wrong: the changes to
PageCacheTagsIntegrationTestat the bottom are just noise; the rest shows the actual changes.Comment #113
webchickBoink!
Comment #115
catchThis looks great, couldn't find things to complain about. Agreed with leaving the debug() statements in.
haha
Committed/pushed to 8.0.x, thanks!