Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I programmatically set cache age for a module in Drupal 8?

Drupal 8:

I have the code for a block successfully doing its work and returning it. The block is called "RacerProfile" and it dumps all its content into variable "$pageContent". At the very end it returns the #markup. Ok. Now how do I tell this to invalidate every six hours?

/**
 * Provides a 'Racer Profile' Block
 *
 * @Block(
 *   id = "racer_profile",
 *   admin_label = @Translation("Slider v1 block")
 * )
 */
class RacerProfile extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() 
    {
    // does all the work to make $pageContent via non-drupal 
    // database queries. However, for this example, let's just
    // just imagine it gets the time of day. Then, let's set
    // let's set the cache age to 5 seconds so F5-F5-F5-F5... should
    // show 12 changes per minute on a repeatable schedule

    $pageContent.= "<p> Date and Time: " . date("F jS Y h:i:s A");
    return array(
      '#markup' => $pageContent,
      '#cache' => ['max-age' => 5 ,],
    );

    }
 }

In other Drupal answers, I've seen "D8 has cache tags and contexts that will automatically invalidate the block if something changes." Fine, but my code is checking a second database. There's no way for Drupal to know what's changing over there. (Without checking, obviously.) So how do I add cache tags with specified timeouts? (Or do cache tags even do that?) I can't find examples.

Notes:

-The code above does not produce the desired result. The page is static to anonymous users. It only changes when a user/admin clears the cache via the web admin.

-Obviously, this is not related to the Maximum Cache age within the admin area of Configuration > Performance > Caching > Page cache maximum age. I don't want this to apply to the entire site, just this block. Additionally, that setting apparently doesn't control this aspect of caching anyway, but instead the cache info that plopped into the header of the rendered pages.

-Obviously, this is not related to settings.php in any way either, since again I don't want to have this apply to the entire site, and the various modules will have different timeout requirements.

-The traffic for the site is relatively low volume, so if rendering a thing four times a day even it only needs to be done once a day isn't a problem. Every six hours means that it's changed before people wake up across four time zones. Mostly. ;) I'm explicitly stating here that I'm interested in having this work at all before I worry about optimizing load or usage.

-I have multiple custom blocks with different expiration periods.

-I certainly have googled it plenty, and have yet to find examples that specifying a specific (measured in a unit of time) timeout for a module block. Even within the D8 module examples on drupal.org

-Importantly, the block needs to have its cache controlled for anonymous users. People with no accounts, "the public" browsing the site.

like image 244
Anders8 Avatar asked Jun 14 '16 21:06

Anders8


1 Answers

To your block's render array you can add cache settings:

'#cache' => [
    'max-age' => 60 * 60 * 24,
],

Time here is measured in seconds. See Also: https://www.drupal.org/developing/api/8/cache/max-age

If you do have hints about things that would need to trigger a reset you can use some of the other caching controls. It sounds like you have a very clear sense of what you want cached where and when, so exploring the materials on the cache API is probably worth your time.

Given that you are pulling from a second database, you may also want to explore BigPipe, which isn't what you asked about, but is meant for use cases where it will take a while to gather all the information for a given page. Likely using blocks built via BigPipe would provide a better user experience than data cached in Drupal for a fixed amount of time (the whole cache engine was rebuilt to allow us to get away from that pattern).

like image 185
acrosman Avatar answered Oct 10 '22 16:10

acrosman