Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
comment.module
Priority:
Critical
Category:
Task
Assigned:
Reporter:
Created:
6 Dec 2013 at 14:56 UTC
Updated:
29 Jul 2014 at 23:11 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
xjmBeta blocker as a blocker for #2151459: Enable node render caching.
Comment #2
amateescu commentedThis should do it.
Comment #3
berdirThis just adds the raw number, could this potentially conflict with other similar things? Should the cache key be something like "comment-pager-$page" instead?
Comment #4
amateescu commentedIt cannot confict with other things because these keys are imploded with ':' to form the cache id. I guess adding 'comment-pager-' before the number would be just for cosmetic purposes, but we can do it if you want :)
Comment #5
berdirYes, but the key is added conditionally. What if there's another numeric key after it that's conditional too? So you'd have ....:1:1:... and sometimes just ...:1:... and then it could be either of those and you'd have the same cache id?
Not very likely, but there have been crazier bugs :)
Comment #6
amateescu commentedHah, ok, colour me convinced.
Comment #7
wim leersThe one concern I have is that if people change the "Comments per page" setting, then the cache wouldn't be cleared. There are two potential solutions:
Option 1 seems the simplest and most efficient solution (per-comment field instance cache tags… that doesn't sound very efficient), so that's what I went with.
I ran into two problems when retrieving the
per_pagecomment field instance setting:@todoI added)!@todoI added).Both could be solved by including the necessary data in the comment entity as additional properties. Are there reasons to not do that? Then
CommentViewBuilder::getBuildDefaults()would become simple again.So the current patch needs refinement, but I believe the logical changes are sound.
Note that this also means that we must adjust the cache keys even if there isn't any
?page=XURL query, because if the number of comments per page is changed, then "page zero" (for which there would not be any comment pager-related identifier in the cache keys/ID) won't be updated.(This also shows how Berdir's #5 remark was very important — we could've ended up with two numeric keys just for comments, yet other modules might contribute to it too! Any externally added values to cache keys should be uniquely identified, otherwise they may be misinterpreted.)
Finally: is test coverage a necessity or a nice-to-have?
Comment #8
amateescu commentedWow, overengineering much? :)
Option 1 can lead to too many (potentially stale) cache entries. And I don't understand what's the deal with "per-comment field instance cache tags… that doesn't sound very efficient" for option 2.
There are at least a couple comment field instance settings that can affect the render cache, not just 'comments per page': threading, possibly 'allow comment title'.
So the simplest solution seems to be to invalidate the render cache of all entities of the bundle(s) where the comment field instance is attached.
That being said, I see now that I was terribly wrong in my initial approach. CommentViewBuilder doesn't have anything to do with this, the extra cache key needs to be added to the 'parent' entity, the one that contains the comments, not to the comments themselves.
Comment #9
wim leersI don't see how this is overengineering? This is about correctness. The code seems overengineered for sure, but that's because most necessary metadata is missing.
You're right though that what I proposed still misses to react to other comment settings changes :/ And that's when I realized I've been incredibly DUMB for not seeing that the
$entity_type . '_view'cache tag is already taking care of all this :/ I'm just overcomplicating things. I guess that's what you meant, then?So #6 was indeed already all we needed to add. Except that it's indeed appending its cache key to the wrong entity. I'm working on fixing that.
Comment #10
amateescu commentedYeah, I guess overcomplicating would've been a better term :/
Comment #11
wim leersThe solution is simple and elegant :)
Multiple comment field pagers hell :)
Sadly, it's complicated by the fact that #731724: Convert comment settings into a field to make them work with CMI and non-node entities made it possible to have multiple comment fields per entity type… yet it failed to update the pager to ensure each comment then has its unique pager. That may seem like an exotic edge case, but without unique pagers, we cannot update the render cache key correctly either! Sadly, that in turn seems to require pretty extensive changes to all of Drupal core's pager logic contained in
pager.inc, which only allows one to assign a numeric identifier to a pager, to allow for multiple pagers on a page. But that's problematic too, because it makes it impossible (AFAICT) for us to figure out which pager belongs to which comments reliably.So, the current sad reality is that the one
?page=Xquery will control all comment pagers simultaneously. And if one set of comments requires e.g. 2 pages and the other requires 5 pages… then you'll only be able to view 2 pages of either set of comments!In other words: pager handling in general looks like it needs to be refactored. But that's obviously out of scope.
So, for dealing with all that, I opened a new issue at #2155387: Multiple comment fields per entity are supported, but break horribly when they need pagers.
Comment #12
andypostI'd like to point about ability to have more formatters fo comment field...
Initially the idea was to move per-page and threading settings to formatter layer, and there should be a @todo in code, but I faced with paging issue and cache for each view mode so delayed this.
So probably moving this settings to formatter level should solve cache granularity but pagers still suck, #33809: Make pagers not suck
Comment #14
wim leersShould be green now.
Comment #16
berdirYou should use foreach ($entity->getPropertyDefinitions() as $definition) here, getProperties() might have to instantiate a lot of field item and list classes, especially as you don't need $field at all. You could also use $definition->getName() instead of $field_name, not sure what's better readable.
Comment #17
amateescu commentedFamous last words :D
Comment #18
berdirYes. *Never* write that in a comment. Even if you only made a single comment change, after that comment, the patch isn't going to apply anymore, the bot will explode or the world will end, but the patch will *not* be green :)
Comment #19
amateescu commentedWe should create a text filter that replaces those phrases with something like "$user thinks this patch will be green. HAHA!" :P
Comment #20
wim leersBut but but … it was a legitimate failure and I fixed it locally! :(
Thanks for the advice, Berdir, I'll fix that :)
Comment #21
wim leersIn this reroll:
I'm postponing this patch on that patch, though.
CommentPagerTestdetected that problem). A simple fix ensures thatCommentViewBuilder::resetCache()gets called, which fixes the problem.(That change could either be part of this patch or the patch in #2151459: Enable node render caching, but I think we might as well fix it here.)
Comment #22
amateescu commented#2155387: Multiple comment fields per entity are supported, but break horribly when they need pagers is in, we should be good to go here.
Comment #25
berdir21: 2151457-21.patch queued for re-testing.
Comment #26
amateescu commentedI hope people won't frown upon rtbc-ing stuff I worked on, the patch cannot get any simpler :)
Comment #27
msonnabaum commentedActually, I think it can get *slightly* simpler.
Using the request and calling pager_find_page was a bit awkward. This just uses get() with the default value instead of has().
Comment #28
msonnabaum commentedComment #29
amateescu commentedExcept that's not what we want..
\Drupal::request()->query->get('page')returns a string of page numbers imploded with "," if we have multiple pagers.Comment #30
msonnabaum commentedDamn, you're right. So ignore #27, #21 is still RTBC
So I still think that's really unfortunate the way it is, but I don't see another way without moving the pager function into a new class where we can also do the has(), but that can easily be done in a followup.
Comment #31
webchickThis feels catch-ish to me.
Comment #32
catchCould we put the $request->query->has('page') first? Then we can bail out before checking the property conditions if there isn't one.
Comment #33
catchComment #34
wim leersGood point. I can move that condition even higher though! :)
Interdiff against #21.
Comment #35
catchCommitted/pushed to 8.x, thanks!
Comment #36
wim leersThanks!