Closed (fixed)
Project:
Flag
Version:
8.x-4.x-dev
Component:
Flag core
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
9 Sep 2015 at 09:35 UTC
Updated:
28 Sep 2015 at 12:54 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
giancarlosotelo commentedProviding a patch. Im not sure if is the way to solve this problem.
Comment #3
berdirHm.
We should try to fix the tests properly, the module eventually needs to work with dynamic page caching. I guess we could commit this as a workaround but we should have an issue open to fix it.
Very likely, the problem is in flag_entity_build_defaults_alter(). That alters how e.g. a node is cached and it caches two different versions of it, one with a flag link and one with an unflag link.
The problem is that the page cache doesn't know of those two variants and which version to use when.
Likely the best problem to solve this is to replace this completely and instead use a lazy_builder to generate the link. There's already a related issue open that needs that anyway: #2466703: Flag reload and AJAX link types are missing a token. So we could commit this and revert this change again there.
See NodeViewBuilder for an example of this, you just register a #lazy_builder instead of actually doing something.
Comment #4
socketwench commentedIf we commit this as a workaround, we need to add a @todo here, referencing the core CR and our own issue for the proper fix.
Comment #5
socketwench commentedUpping to critical since this is blocking tests.
Comment #6
socketwench commentedComment #7
giancarlosotelo commented@todo added with references
Comment #8
wim leersI haven't looked at the code nor the test failures.
But in general, failures with Dynamic Page Cache enabled indicate that something is being cached across authenticated users when it should not be. I.e. a certain cache context is missing that tells Drupal something is actually per user, per session, per something.
Comment #9
joachim commentedI think we should maybe fix this now rather than postpone it. There aren't any pressing issues that need work on or big patches that would get broken by this, so we should focus our attention on this.
Comment #10
socketwench commentedI think you may be right, but I have the sinking feeling that to fix this we have to disable the reload link type if caching is enabled, and then load the flagging state over AJAX.
Comment #11
socketwench commentedI chatted with larowlan about this earlier tonight. His suggestion was to try one of two paths:
He suggested talking to Wim Leers for ideas.
Comment #12
wim leersCan you point to the relevant pieces of code in Flag? Happy to help here.
Comment #13
berdirConfused, isn't 1. exactly what I described fairly detailed in comment #3?
I don't think cache tags help, unless we'd cache per-user in the first place, but that's a bad idea.
One example that needs to be updated is flag_entity_view(). Instead of actually displaying a link, we just need to register a lazy builder and then display the actual link in there.
Comment #14
wim leers#3 and #13 definitely sound good.
Comment #15
berdirWe need something like this, basically.
I found a bug in the lazy builder logic, it doesn't work correctly for top-level #type elements, so I put it in a sub-element. I think we need to re-enter the whole render process, to also consider #access on the top-level element and possibly other logic that happens before calling it. I guess Wim will open an issue for this, I need to go for now.
Did run just one test but that passed. Needs work for documentation and stuff, of course.
Comment #17
socketwench commentedAdmittedly, I was trying to summarize what I didn't quite understand well past my bedtime.
Comment #18
berdirOk, a lazy builder must return an array, not so great DX but easy to fix. This passes for me locally.
Comment #19
fabianx commentedRTBC - Looks great to me.
I love how this isolates the things and makes it unnecessary to tamper with the entities #cache.
The below is for discussion with berdir / Wim and not meant for this patch, just giving additional context from the 'core' side of things.
It is a little on purpose, because that way #type can specify it wants to be lazy builded IIRC.
Yeah, should probably cast NULL into [].
Comment #20
joachim commentedYay! Tests pass!
Do we need render cache tags? I don't see that we have any at the moment, so that can be taken care of in a follow-up if we should have them.
> Ok, a lazy builder must return an array, not so great DX but easy to fix.
Same way a form builder has to return at least an empty array. But yeah, casting NULL to [] would be a little bit of DX sugar.
Comment #21
socketwench commentedI keep looking at this and thinking, "Oh, that's why this shouldn't be a straight function..." It clearly works as one, but what I saw in CommentDefaultFormatter was in a separate service. I'm not sure what the implications are for not using proper DI here, but that can be in a follow up issue.
Comment #22
berdir@Fabianx: We need to find a different place (aka core issue) to continue discussing this. Yes, #type's should be allowed to have lazy_builder's too, but that shouldn't stop us from at least loading the defaults again after calling it based on getInfo(). We'd just do it twice. Or, i was wondering if we shouldn't just do $this->doRender($new_elements) at that point or something like that. What if you specifiy top-level #access on a lazy-builder return value? That won't be checked either right now.
@joachim:
We don't need cache tags to fix this. What we do need to do is invalidate the {$entity_type_id}_view cache tag ($view_builder->resetCache()) whenever we create, change or delete a flag, somehow trough the type plugin. I was thinking about adding a cache tag for the flag, but the problem is that we can't solve it for *new* flags anyway, so those need to invalidate all existing render cached nodes. To reproduce, create a node first, then create a flag, or create a second flag, that won't be shown until a cache clear happens. I think.
But that's a separate issue and pre-existing situation.
@socketwench: Yeah, I was just too lazy to create a service and all. We could put it in flag service i guess that would be an easy change.
Comment #24
joachim commentedCommitted, with just a couple of minor fixes to typos in comments.
Several follow-ups / related issues:
- move this to the flag service? #2568129: Move lazy builder callback into a service.
- add cache clearing #2568131: clearing entity caches on flag changes