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