Problem/Motivation
See #2430341: Comment pager-dependent cache key should be a cache context for a sister issue and #2429287: [meta] Finalize the cache contexts API & DX/usage, enable a leap forward in performance for the overarching meta.
For prior discussion, please read everything in #2433599: Ensure every (non-views) pager automatically associates a matching cache context!
Blocks #2381277: Make Views use render caching and remove Views' own "output caching"
Proposed resolution
Views using pagers should specify a cache context.
Remaining tasks
| Task | Novice task? | Contributor instructions | Complete? |
|---|---|---|---|
| Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards | Instructions |
User interface changes
No.
API changes
Extra optional argument preserves previous behavior, so no BC break.
- public function setCurrentPage($page) {}
+ public function setCurrentPage($page, $keep_cacheability = FALSE) {}
in setCurrentPage() setItemsPerPage() setOffset()
| Comment | File | Size | Author |
|---|---|---|---|
| #68 | interdiff.txt | 1.17 KB | dawehner |
| #68 | 2433591-68.patch | 10.34 KB | dawehner |
| #54 | 2433591-53.patch | 10.34 KB | yesct |
| #54 | interdiff.49.53.txt | 514 bytes | yesct |
| #49 | 2433591-49.patch | 9.84 KB | yesct |
Comments
Comment #1
wim leersAlready taken care of by #2433599, see #2433599-7: Ensure every (non-views) pager automatically associates a matching cache context.
Comment #2
fabianx commentedRe-opening to take the views parts into account.
Views has a setPager method and we need to deal with that somehow in regards to cache context.
We'll find a solution :).
Comment #3
wim leersComment #4
wim leersLet's postpone this on #2433599: Ensure every (non-views) pager automatically associates a matching cache context.
We can discuss stuff here already, but patches are postponed on that issue.
Comment #5
wim leers#2433599: Ensure every (non-views) pager automatically associates a matching cache context is in, this is now unblocked.
Comment #6
dawehnerIs this all we need?
Comment #7
wim leersIs that patch trying to say "use the regular pager cache context, but enforce the Views pager's 'current page'"?
Comment #8
dawehnerYeah, would that make sense?
Comment #9
wim leersThat makes sense conceptually, yes. But we need the "Views' pager 'current page'" to be derived from some request context. i.e. the pager cache context is derived from the URL's query arguments. We need something similar for "Views' pager 'current page'". If we don't have that, then there is no way to calculate the current page without executing the entire view…
So, what is the shortest path to calculating the "Views' pager 'current page'"?
Comment #10
dawehnerLet's give another example.
Random code in your template preprocess:
There is a world beyond pages :)
Comment #11
fabianx commentedIn that case the template code needs to specify manually what it wants this to be varied on in my opinion.
Does $view->preview() show a pager, btw.?
Comment #12
dawehnerYes it does.
Comment #13
dawehnerWell, I still think that if we could do something about it, we should do, because otherwise there will be just tons of bugs by people all over the place.
Comment #14
fabianx commentedI agree and it is not forgotten.
So what should we do?
Lets work on some test cases?
Or we could use the 'hard, but correct method' and set max-age==0 when you use setPage() as we cannot determine if you do:
but if you know what it varies on you would need to specify something like this for example:
What do you think?
Comment #15
andypostI'd like to point that view can render nodes with comments but comment formatter provides own "dumb" setting for pager.
Was done in #2155387: Multiple comment fields per entity are supported, but break horribly when they need pagers and #2430341: Comment pager-dependent cache key should be a cache context
So you can easily get in situation (probably in tests) where the same cache context would be exposed from comment field and view itself.
Comment #16
dawehnerLet's see ...
The idea is: once you have those methods, you opt out of caching, but if you want, you can opt in and provide your corresponding cache contexts.
Comment #17
plachThe last patch makes sense to me, but in the case of regular page displays I guess we could keep caching enabled and specify the regular pager contexts.
Comment #18
wim leersSo, in reviewing this, I noticed there is one non-test call to
::setCurrentPage(): inCachePluginBase, where data is being retrieved from the results cache. While that should have caused any view using the results cache to have amax-ageof zero, it did not. The reason for that turned out to be that\Drupal\views\ViewExecutable::attachDisplays()clones itself, and the clone'selementproperty is then used, thus causing themax-agezero on the original (uncloned) view executable to be ignored.In other words: this particular thing is only resulting in the correct end result (non-zero max age) despite not using the
$keep_cacheability = TRUEability thanks to a bug deeper in Views…Thanks to @plach for the help while debugging.
@plach suggested syncing the
elementproperties across clones.Comment #19
plachSo we need to ensure
CachePluginBasedoes not make things uncacheable when retrieving results.Comment #21
plachSpoke with Daniel: #18 is the wrong fix. This addresses #19, I'll test this a bit more to see what I can do to fix #18.
No interdiff as I touched almost every line.
Comment #23
plachOMG, I actually posted the interdiff instead...
Comment #24
plachThis makes pagers actually work with cached full views. Still investigating Wim's issue.
Comment #26
plachFixed failures
Comment #30
dawehnerWe should ensure to not include that as part of the patch, right?
Comment #31
plachMeh, too many branches
Comment #32
dawehnerIndeed
Comment #33
plachCorrect interdiff
Comment #35
dawehnerAdded the needed expected cache contexts.
Comment #36
plachI think this should be ready to go. I investigated Wim's issue but I cannot reproduce it: when result cache is enabled (and
$this->view->setCurrentPage($cache->data['current_page'], TRUE)is changed to$this->view->setCurrentPage($cache->data['current_page'])) max age is 0 and the view is not cached as expected.Comment #37
plachUnintended status change
Comment #38
plachComment #39
dawehnerThere we go, added test coverage for it.
Comment #40
dawehnerHere is the test which will fail as well.
Comment #41
dawehnerAnd the interdiff
Comment #43
plachFixed missing PHP doc, aside from that looks great to me.
Comment #44
dawehner+1
@wim
Do you mind reviewing stuff again?
Comment #45
catchBlocks #2381277: Make Views use render caching and remove Views' own "output caching", bumping to critical.
Comment #46
catchShould this explain what to do if you set $keep_cacheability to TRUE?
Also 'mark the issue' - should it be 'mark the view'? - this is repeated each time the doc is added.
Comment #47
yesct commentedComment #48
dawehnerHa!
Explained a bit, why we need this parameter and why its FALSE by default, feel free to improve it.
Comment #49
yesct commentedjust some grammar changes I noticed in the last interdiff.
Next I'll read the whole thing.
Comment #51
yesct commentedif it is not cacheable, we override whatever it might be. (daniel says we dont know what it is yet, and could be set in a views setting.)
In the test, we test for 0 (not cacheable) and -1 (permanent), but seems we do not have a test that tests the value from the setting actually bubbles up.
Maybe we should add a test for that?
------
Everything else looked ok to me. (read the whole patch)
Does not seem to need manual testing or anything, because the test is checking the header to see if the context for the page is added.
#2381277: Make Views use render caching and remove Views' own "output caching" will be the issue that will use that context in the header to actually use the context.
Comment #53
yesct commentedValue array ( 0 => 'languages:language_interface', 1 => 'theme', 2 => 'url.query_args.pagers:0', 3 => 'url.query_args:order', 4 => 'url.query_args:sort', ) is identical to value array ( 0 => 'languages:language_interface', 1 => 'theme', 2 => 'url.query_args:order', 3 => 'url.query_args:sort', ). Other FieldWebTest.php 81 Drupal\views\Tests\Handler\FieldWebTest->testClickSorting()
fail is from #2489966: The Views table style plugin does not specify cache contexts for click sorting which added a test that went in today. I'll fix it now.
Comment #54
yesct commentedjust added the new pager context to that test.
test passes locally.
Comment #55
yesct commentedThinking more, the test I asked about in #51 is probably not worth delaying this critical. So I opened a normal task to add the test (and discuss if we need it). #2490852: Add a test for views pager cache age setting
Comment #56
yesct commentedupdated the issue summary.
I'm guessing we do not need a change record for this. #2381277: Make Views use render caching and remove Views' own "output caching" probably doesn't need one either...
Comment #57
fabianx commentedRTBC, Let's get this in.
Test coverage looks good, we know that bubbling works from other tests, too.
The solution to explicitly opt-in to keep the current cacheability looks great!
Comment #58
yesct commented@tim.plunkett and I were trying to see the page cache tag in the browser... and we haven't figured out how to see it on admin/content (yet)
Comment #59
yesct commentedI can see it on a view I made.
Comment #60
tim.plunkettReading through \Drupal\Core\Cache\CacheContextsManager::optimizeTokens() @YesCT and I finally figured out why we couldn't see
url.query_args.pagers:0, becauseurlis already included and is an "ancestor", so the more specific context is not needed.RBTC +1
Comment #61
dawehnerThank you for the final push @yesct!
Its amazing how things work together at the end.
Comment #62
wim leersUgh, I wrote this before #47, but didn't notice I'd cross-posted which caused my comment not to actually be posted :/
I can still reproduce this. Using the front page view, with tag-based caching enabled. With or without the cited
TRUE, the front page gets an output cache item.Due to the above, also feeling less bad for pointing out nitpicks.
Nitty nit: s/pager related/pager-related/
Nit: s/kept on -1/unchanged/
Comment #64
catchThanks for the additional docs.
Committed/pushed to 8.0.x, thanks!
Comment #65
wim leersHrm, catch was probably already committing while I posted #62. Moving back to "active" to see if others can confirm the problem I found. Not sure if we want a revert here, or fix that in a follow-up.
Comment #66
catchYes that was an awful cross-post.
I've gone ahead and reverted for #62, back to CNW.
Comment #68
dawehnerSo the corresponding cache contexts don't appear in the HTTP response?
I try to understand what you actually expect as part of this issue. Output caching doesn't use render caching ... but output caching relies on $view->result which itself depends on the dynamic pager data:
aka. we don't need such workarounds for output caching in its current form. Plach and I talked about getting rid of output caching though, but for sure, this is 100% out of scope of this issue.
I don't consider this as a blocker of the issue itself.
Fixed the nits ...
Comment #69
fabianx commentedAssigning to Wim to provide:
- Steps to reproduce
Comment #70
Aki Tendo commentedLooked over the code and ran all the tests locally under PHP 5.5 with no issues. RTBC?
Comment #74
wim leersMy apologies, I was indeed setting render caching expectations, but this is Views' output cache, which behaves differently.
Comment #75
fabianx commentedYes, lets create a follow-up to remove the output cache - as its broken currently anyway due to no bubbling support.
We could also do it as part of the parent: "Make views use render-caching issue" though.
Comment #76
wim leersThat's how I always imagined we'd do it.
Comment #77
catchCommitted/pushed to 8.0.x, thanks!
Comment #79
plachRemoving output caching will happen in #2381277: Make Views use render caching and remove Views' own "output caching", see the proposed solution.