Comments

wim leers’s picture

Status: Active » Needs review
StatusFileSize
new9.16 KB

Status: Needs review » Needs work

The last submitted patch, 1: 2464659-1.patch, failed testing.

wim leers’s picture

Assigned: wim leers » Unassigned
Status: Needs work » Needs review
StatusFileSize
new12.42 KB
new3.37 KB

Green!

wim leers’s picture

Having this in a separate subscriber might be clearer, but adding more event subscribers doesn't come without a cost, of course.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/modules/system/src/Tests/Bootstrap/PageCacheTest.php
@@ -237,6 +239,57 @@ function testPageCache() {
+    $config = $this->config('system.performance');
+    $config->set('cache.page.use_internal', 1);
+    $config->set('cache.page.max_age', 300);
+    $config->set('response.gzip', 1);
+    $config->save();

I think we should have helpers for those calls (enable / disable) in general in WebTestBase.

Why gzip here?

Can all be follow-up though.

--

RTBC, test changes look great!

wim leers’s picture

That was just C/P. We can remove many of those calls in #2465053: Drupal 8 only allows one user every 6 hours to register when page caching is enabled — caused by entity UUID in form state. Yes, let's clean that up (since it's now a new problem: many, many tests across core do this) in a follow-up issue.

xjm’s picture

Priority: Major » Critical

#606840: Enable internal page cache by default is currently marked critical, so if this is a hard blocker, then it's critical as well.

dawehner’s picture

+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -139,6 +139,22 @@ public function onRespond(FilterResponseEvent $event) {
+    // The 'user.permissions' cache context ensures that if the permissions for
+    // a role are modified, users aren't served stale render cache content. But,
+    // when entire responses are cached in reverse proxies, the value for the
+    // cache context is never calculated, causing the stale response to not be
+    // invalidated. Therefore, when varying by permissions and the current user
+    // is the anonymous user, also add the cache tag for the 'anonymous' role.
+    $cache_contexts = $response->headers->get('X-Drupal-Cache-Contexts');
+    if ($cache_contexts && in_array('user.permissions', explode(' ', $cache_contexts)) && \Drupal::currentUser()->isAnonymous()) {
+      $cache_tags = ['config:user.role.anonymous'];

Its a bit odd that we introduce a special case in the FinishResponseSubscriber which seems to be for me a pretty generic place. Don't we actually need an API to provide additional cache tags given you have some cache contexts?

webchick’s picture

Status: Reviewed & tested by the community » Needs review

I actually had the same thought. I would hate for contrib modules to have to write that sort of shenanigans a lot... seems like it's really easy to get that wrong.

fabianx’s picture

Priority: Critical » Major
Status: Needs review » Needs work

Yes and No:

It _is_ a very special case, because we don't want external proxies / internal page cache to depend on the user.permissions cache context, but use the cache tags instead.

However:

a) This shows there is a bug with the PageCacheMiddleware not taking contexts into account from the header as context.permissions should work and the parent 'enable page cache' should not fail. Fixing that is the real fix for the 'enable page cache issue' (and this can be demoted to major again as it is an optimization).

b) This should be more an alter cache contexts alter event / alter hook.

What should be happening here instead is:

- Call alterCacheMetadata event with a BubbleableMetadata or CacheableDependenyInterface object (whatever we want).
- User module implements the event / hook (whatever is appropriate)
- If cache_context user.permissions is present AND user.isAnonymous(), add the cache tag and _remove_ the context (that is important to distinguish from authenticated user processing)

fabianx’s picture

Issue tags: -blocker
fabianx’s picture

Priority: Major » Critical
Status: Needs work » Needs review
Issue tags: +blocker

a) However is not easy to fix as we need all the #cache_redirect logic of the renderer for that. Opened #2466585: Decouple cache implementation from the renderer and expose as renderCache service for that.

Sorry for the ping-pong, I still think its better to support a first alteration of the cache contexts header, because even if the page cache supports cache contexts, it is important to have in the ideal case only the 'url' cache context at the top level to avoid expensive service invocations.

If we want we can include the API here - however I am also okay to put that to a follow-up.

wim leers’s picture

#8 + #9: that's why I said this in #4:

Having this in a separate subscriber might be clearer, but adding more event subscribers doesn't come without a cost, of course.

Happy to do that.


#10:
a) No, the page cache must behave like any other reverse proxy; it should NOT take cache contexts into account, because other reverse proxies handling anonymous user requests won't be able to do that either. It also needs to remain as simple and fast as possible, so it should look only at the URL.

b) I don't see why an alter event or hook is necessary, if we already have the response event.


#12: please keep any "cache context + page cache" discussion for a separate issue. It'd be a quite big departure from how it has always worked. I don't want to get this last blocker for enabling the internal page cache by default to get sidetracked.

fabianx’s picture

I am totally fine with just moving the current logic to a different subscriber as written, however I would ask that we also remove the user.permissions cache context while adding the tag as it is no longer needed.

wim leers’s picture

StatusFileSize
new15.33 KB
new10.07 KB

As discussed in IRC with @dawehner & @Fabianx.

Also fixed the #5 nitpick and added more tests.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

And back to RTBC any API to simplify that can be follow-up.

rteijeiro’s picture

StatusFileSize
new14.72 KB
new3.44 KB

Fixed a couple of nitpicks in comments so I guess it's still RTBC.

dawehner’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/EventSubscriber/AnonymousUserResponseSubscriber.php
@@ -0,0 +1,84 @@
+    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
+      return;
+    }

Quick tip: You can use $event->isMasterRequest()

wim leers’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new16 KB
new1.5 KB

Ok, also fixed in FinishResponseSubscriber, which is where I copied that bit of code from.

dawehner’s picture

Thank you for fixing that nitpick.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Looks right here. Committed/pushed to 8.0.x, thanks!

  • catch committed 996eb16 on
    Issue #2464659 by Wim Leers, rteijeiro: Routes that are varied by the '...
wim leers’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

cilefen’s picture