Scheduling fails with Drupal page cache and cache.page.max_age set to 0

Created on 19 December 2020, over 3 years ago
Updated 8 January 2024, 6 months ago

Problem/Motivation

Here's a "gotcha" with this module, due to the bizarre behavior of Drupal's page cache. If you set your Drupal's page cache to <no caching> ('cache.page.max_age' == 0) and you have drupal's page cache turned on for anonymous users, pages are cached with no expiration. This breaks the scheduling feature in Sitewide Alert.

This is because the page cache for the /sitewide_alert/load is saved with expire: -1 in this case.

In order for this feature to work, 'cache.page.max_age' must be greater than 0. Otherwise the expire set below is overridden in FinishResponseSubscriber::onRespond(), as the response is set to not be cacheable. But rather than it not caching, the page cache ignores that it's not cacheable and caches it anyway. See https://www.drupal.org/project/drupal/issues/2835068 πŸ› PageCache caching uncacheable responses (violating HTTP/1.0 spec) + D8 intentionally disabling HTTP/1.0 proxies = WTF Needs work

    // Set the date this response expires so that Drupal's Page Cache will
    // expire this response when the next scheduled alert will be removed.
    // This is needed because Page Cache ignores max age as it does not respect
    // the cache max age. Note that the cache tags will still invalidate this
    // response in the case that new sitewide alerts are added or changed.
    // See Drupal\page_cache\StackMiddleware:storeResponse().
    if ($expireDate = $this->sitewideAlertManager->nextScheduledChange()) {
      $response->setExpires($expireDate->getPhpDateTime());
    }

Steps to reproduce

1 Enable Drupal's page cache module
2) set Browser and proxy cache maximum age set to <no caching> at /admin/config/development/performance
3) Create an alert that is scheduled to start in a minute and is active.
4) in a private browser window (incognito window) so you're logged out, visit the site in a minute. The alert doesn't appear.
5) Check the cache_page table in the database:

select * from cache_page where cid = 'https://mdb.uscourts.local/sitewide_alert/load:' \G

Notice that the expire is set to -1, this means the page cache won't expire as it should:

expire: -1

6) Now go to /admin/config/development/performance and set the Browser and proxy cache maximum age set to something other than <no caching> such as an hour, or one minute.

7) Create an alert that is scheduled to start in a minute and is active.
4) in a private browser window (incognito window) so you're logged out, visit the site in a minute. The alert will appear.

Proposed resolution

If there's some way to alter the cache in this situation we should do that. Otherwise we should document the bug.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ“Œ Task
Status

Postponed: needs info

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States oknate Greater New York City Area

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States ChrisSnyder Maryland

    @swirt are you using any other caching layer like redis, varnish, or memcache?

  • πŸ‡ΊπŸ‡ΈUnited States swirt Florida

    We are using memcache.

  • πŸ‡ΊπŸ‡ΈUnited States ChrisSnyder Maryland

    @swirt, Does this issue also occur when you disable memcache? This could be tested on your non-production staging or development environments.

    I am curious if memcahe has a similar issue to the one redis had. The one documented in the project's README and needs a patch to resolve.

  • Status changed to Postponed: needs info over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States ChrisSnyder Maryland
  • First commit to issue fork.
  • This issue affects a clean Drupal installation without memcache or redis - I was able to replicate the issue using a DrupalPod gitpod instance.

    The issue should ideally be fixed upstream, but it's quite a big change in core's behaviour (especially with the number of failing tests), so I've opted to simply invalidate page caching within the module instead.

Production build 0.69.0 2024