We've found that the bubbled max age in some circumstances is lower or higher than we'd like, especially when a site has a cache layer (e.g Cloudfront) in combination with no purging solution.

In the case of max ages being high, such as infinite or multi-day, as a workaround for lack of a purging solution, we'd like to cap the bubbled max age to a configurable ceiling.

In the case of low max age, but not uncacheable, we'd like to enforce a minimum cache age to reduce the load on the server.

Ideally if a proper purging solution is added to a site, the max-age maximum cap would be lifted.

The patch provides the necessary plumbing, configuration is currently set using config overrides in line with a previous issue (#2878459: Remove configurability: simpler to set up (because works immediately), easier to maintain) to make the module UI-less.

Sample configuration for a settings.php

// Values are seconds, valid values are integers greater than zero.
$config['cache_control_override.settings']['max_age']['minimum'] = 1000;
$config['cache_control_override.settings']['max_age']['maximum'] = 9000;
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

dpi created an issue. See original summary.

dpi’s picture

Assigned: dpi » Unassigned
Status: Active » Needs review
StatusFileSize
new10.34 KB

Patch includes tests.

Test module has been updated to allow for responses without max age.

I've intentionally not shipped any default configuration, as default values should be null.

dpi’s picture

jibran’s picture

Neat idea patch looks good to me.

  1. +++ b/src/EventSubscriber/CacheControlOverrideSubscriber.php
    @@ -43,10 +61,40 @@ class CacheControlOverrideSubscriber implements EventSubscriberInterface {
    +        if (isset($minimum)) {
    +          $max_age = max($minimum, $max_age);
    ...
    +        if (isset($maximum)) {
    +          $max_age = min($maximum, $max_age);
    

    Let's add some comments here.

  2. +++ b/src/EventSubscriber/CacheControlOverrideSubscriber.php
    @@ -43,10 +61,40 @@ class CacheControlOverrideSubscriber implements EventSubscriberInterface {
    +  protected function getMaxAgeMinimum() {
    ...
    +  protected function getMaxAgeMaximum() {
    

    Why not getMinimumMaxAge() and getMaximumMaxAge()?

dpi’s picture

Added extra docs.

Why not getMinimumMaxAge() and getMaximumMaxAge()?

I prefer the symmetry/alphabetical ordering. Isn't a concern either way.

jibran’s picture

Status: Needs review » Needs work

We need to add config/install/cache_control_override.settings.ymland a hook_update_N to add it to active storage.

jibran’s picture

Status: Needs work » Needs review
StatusFileSize
new836 bytes
new11.34 KB

Here you go.

jibran’s picture

StatusFileSize
new996 bytes
new12.09 KB

Added schema test.

jibran’s picture

StatusFileSize
new1.42 KB
new12.11 KB

Fixed the failing test.

marcoscano’s picture

Status: Needs review » Reviewed & tested by the community

Nice work! This is 👍 from me. I have found just some nitpicks, feel free to disregard if you like.

  1. +++ b/cache_control_override.install
    @@ -0,0 +1,17 @@
    +function cache_control_override_update_8101() {
    +  \Drupal::configFactory()
    +    ->getEditable('cache_control_override.settings')
    +    ->set('max_age.minimum', 0)
    +    ->set('max_age.maximum', -1)
    +    ->save(TRUE);
    
    +++ b/config/install/cache_control_override.settings.yml
    @@ -0,0 +1,3 @@
    +max_age:
    +  minimum: 0
    +  maximum: -1
    

    I'm confused why these default values are necessary, especially due to these descriptions:

    Minimum max age, if max age is greater than 0. Leave empty to disable.

    Maximum max age, if max age is greater than 0. Leave empty to disable.

    Wouldn't a "no limit by default" be reasonable so that we don't need the install hook and initial values?

    (also, in case we do want to leave them, maybe using Cache::PERMANENT instead of -1 would make it more self-explanatory?
    (It's a bit unfortunate #2951046: Allow parsing and writing PHP class constants and enums in YAML files is not in yet so we could use it in the yml file, but at least in the update hook it could make sense? :) )

  2. +++ b/src/EventSubscriber/CacheControlOverrideSubscriber.php
    @@ -43,10 +61,44 @@ class CacheControlOverrideSubscriber implements EventSubscriberInterface {
    +        // Force maximum max-age if configured.
    +        $maximum = $this->getMaxAgeMaximum();
    +        if (isset($maximum) && $maximum != Cache::PERMANENT) {
    +          $max_age = min($maximum, $max_age);
    +        }
    

    I guess we could enforce $maximum here to also be > 0, even though I admit this is borderline paranoia, since the value can only be defined in settings.php... :)

dpi’s picture

I'm confused why these default values are necessary, especially due to these descriptions:

Wouldn't a "no limit by default" be reasonable so that we don't need the install hook and initial values?

I think its just that when introducing new configs, you should set an initial value. The minimum 0 and maximum -1 values effectively disable this feature for new and existing sites.

maybe using Cache::PERMANENT instead of -1 [...] but at least in the update hook it could make sense? :) )

Yep, done.

I guess we could enforce $maximum here to also be > 0, even though I admit this is borderline paranoia, since the value can only be defined in settings.php... :)

Yeh probably not necessary, especially low values are unlikely. "Max age maximum" is self explanatory.

dpi’s picture

Pushed the patch as a MR above^

kim.pepper’s picture

Issue tags: +#pnx-sprint

  • dpi committed 55f090f on 8.x-1.x
    Issue #3003716 by dpi, jibran, marcoscano: Coerce bubbled max-age to a...
dpi’s picture

Version: 8.x-1.x-dev » 2.0.x-dev
Assigned: Unassigned » dpi
dpi’s picture

Gitlab/d.o are quite broken at the moment so the 2.x/Drupal 10 version of this MR will need to chill for a bit.

  • dpi committed b91dab9 on 2.0.x
    Issue #3003716 by dpi, jibran, marcoscano: Coerce bubbled max-age to a...
dpi’s picture

Assigned: dpi » Unassigned
Status: Reviewed & tested by the community » Fixed

Huzzah! GitLab caught up

Status: Fixed » Closed (fixed)

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