Make Patternkit Pattern Entity Cache Invalidation Configurable

Created on 20 August 2024, about 1 month ago
Updated 19 September 2024, 9 days ago

Problem/Motivation

Every Patternkit block includes cache tags for both the specific Patternkit Pattern entity and the pattern's asset ID, like the following:

  • patternkit_pattern:
    • Example: patternkit_pattern:1
  • pattern:
    • Example: pattern:@patternkit/atoms/example/src/example

This is appropriate to identify the content being rendered and ensure content gets invalidated when related changes take place, but for sites with a lot of content and repetition of the same patterns throughout much of it, unexpected invalidation of a tag spanning a large portion of the site's pages could have a significant performance impact. With the behavior as of the Beta 10 release, both of these tags are invalidated whenever a pattern block is updated to the latest version. Due to the revisioning of the pattern schema and template content into the pattern entity, blocks referencing the specific pattern revision prior to the update the rendered output of these blocks will remain unaffected, but regardless of this, the containing pages will be invalidated due to the entity ID and asset name invalidations being triggered. When a site is using pattern blocks in default layouts, changes from updating the pattern should affect all other pages using the same default layout, and thus the invalidation of those containing pages would be relevant, but this is already accounted for by the display mode cache tag. Alternatively, if a site is primarily using pattern blocks in overridden layouts, updating the pattern for a single instance should not affect other pages and invalidation of them would be unnecessary and wasteful. Sites behind CDN or other caching solutions in front of Drupal may not be as concerned about this broad invalidation, so to account for this diversity, this behavior should be configurable.

Steps to reproduce

Testing for this is best handled on a local environment since it involves tracking cache invalidations and forcing pattern updates which is easiest to accomplished by modifying files locally.

  1. Install a site locally with the following modules enabled:
    • Patternkit
    • Patternkit Example
    • Layout Builder
  2. Enable cache header output →
  3. Configure the Basic Page content type to use layout builder with per-page overrides enabled
  4. Configure the default layout for Basic Page and add an instance of "[Patternkit] Example"
  5. Create 2 new Nodes of the Basic Page content type: Page 1, and Page 2
  6. Edit the layout for Page 2, override the layout saving a change to the content of the example pattern block

This is the behavior as of the Beta 10 release, but returning to this with the new changes in place will require disabling the new setting. For this scenario, we expect to see the caches for all pages containing blocks using the same pattern, whether overridden or in default layouts, invalidated when one block instance is updated. To do this, we'll need to view the site in one browser window as an anonymous user while logged into another window to make the administrative updates being tested.

  1. As an administrator, navigate to the Patternkit settings page at /admin/config/user-interface/patternkit, enable the checkbox for "Entity cache tag invalidation" under "Advanced settings", and click the "Save configuration" button
  2. In your local files, update the template file for the "[Patternkit] Example" pattern to trigger detection of a new update to the pattern being available
    1. Edit the file at modules/patternkit_example/lib/patternkit/src/atoms/example/src/example.twig in the Patternkit module directory
    2. Add some visible markup, such as <strong>UPDATED</strong>, into the template so it will be clearly visible when the new template is used
    3. Clear the Patternkit cache to discover the update: drush pkcc
    4. As an administrator, edit the layout for Page 2, edit the example block, and confirm the button to "Update pattern" is available at the top of the pattern form
  3. As an anonymous user, view both pages confirming a successful cache response on each
  4. As an administrator, edit the layout for Page 2, edit the example block, click the "Update Pattern" button, and save the block. Expect to see the altered content from your template edits visible in the block preview and click "Save layout".
  5. As an anonymous user, view both pages expecting to see a cache miss for each
  6. As an anonymous user, view Page 1 expecting to see the original markup for the example block not including your manual changes
  7. As an anonymous user, view Page 2 expecting to see the altered content from your template edits in the block

The following scenario will test the cache invalidation behavior with the newly exposed setting disabled. This should be the new default behavior after implementing the code changes for this issue and running database updates if the setting has not been manually changed beforehand. With this alteration, updating the pattern for a single block should not trigger invalidation of other pages containing the same pattern.

  1. Ensure all pattern instances are up to date by running drush pkbu
  2. Clear all caches with drush cr
  3. As an anonymous user, view each page twice ensuring the second view returns a cache hit for each
  4. In your local files, update the template file for the "[Patternkit] Example" pattern to trigger detection of a new update to the pattern being available
    1. Edit the file at modules/patternkit_example/lib/patternkit/src/atoms/example/src/example.twig in the Patternkit module directory
    2. Add some visible markup, such as <strong>UPDATED AGAIN</strong>, into the template so it will be clearly visible when the new template is used
    3. Clear the Patternkit cache to discover the update: drush pkcc
    4. As an administrator, edit the layout for Page 2, edit the example block, and confirm the button to "Update pattern" is available at the top of the pattern form (Do not click the button yet)
  5. As an anonymous user, view both pages confirming a successful cache response on each
  6. As an administrator, edit the layout for Page 2, edit the example block, click the "Update Pattern" button, and save the block. Expect to see the altered content from your template edits visible in the block preview and click "Save layout".
  7. As an anonymous user, view all both noting the page cache result
    • Expect to see a cache hit on Page 1 with the content of the block showing the previous edits
    • Expect to see a cache miss on Page 2 with the content of the block showing the latest edits

Proposed resolution

  • Add a configuration option to control whether these cache tags should be invalidated
  • Default this configuration option to prevent widespread cache invalidation on pattern updates

Remaining tasks

User interface changes

  • New "Advanced settings" section on the Patternkit settings page at /admin/config/user-interface/patternkit
    • New "Entity cache tag invalidation" setting

API changes

  • New entity_cache_tag_invalidation configuration value in patternkit.settings

Data model changes

None

✨ Feature request
Status

RTBC

Version

9.1

Component

Module Core

Created by

🇺🇸United States slucero Arkansas

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

Merge Requests

Comments & Activities

  • Issue created by @slucero
  • 🇺🇸United States slucero Arkansas
  • 🇺🇸United States slucero Arkansas

    slucero → changed the visibility of the branch 3469294-make-patternkit-pattern to hidden.

  • 🇺🇸United States slucero Arkansas
  • 🇺🇸United States slucero Arkansas

    After further testing, I've uncovered that the existing behavior (the currently proposed default) is not terribly helpful for several reasons:

    • When patterns are used in the default layout for a content type, the cache tags present for it don't matter as much for invalidation during pattern updates since the related updates to the default layout invalidate a tag like config:core.entity_view_display.node.page.default which is present on every page of that content type using that display mode regardless whether it is overridden. Due to this, every page of that content type will be invalidated regardless.
    • When used on overridden layouts, including the invalidation of the patternkit_pattern:<id> cache tags will result in all pages containing this pattern being invalidated when a single instance of the pattern is updated. These other blocks won't show any changes, however, since they still point to the prior revision of the pattern entity. The same behavior is true for pattern:<asset_id>cache tags which also get invalidated on update with this setting enabled.

    Based on these findings, I'll be updating the default value for this new setting to FALSE which will represent a change in behavior for most sites already. This change should be for the better, however, by bringing cache invalidation more in line with visible changes to the content.

  • Status changed to Needs review about 1 month ago
  • 🇺🇸United States slucero Arkansas
  • 🇺🇸United States slucero Arkansas
  • 🇮🇳India minsharm India

    Steps to test

    1. Install a site locally with the following modules enabled:
      • Patternkit
      • Patternkit Example
      • Layout Builder
    2. Enable cache header output →
    3. Configure the Basic Page content type to use layout builder with per-page overrides enabled
    4. Configure the default layout for Basic Page and add an instance of "[Patternkit] Example"
    5. Create 2 new Nodes of the Basic Page content type: Page 1, and Page 2
    6. Edit the layout for Page 2, override the layout saving a change to the content of the example pattern block
    1. As an administrator, navigate to the Patternkit settings page at /admin/config/user-interface/patternkit, enable the checkbox for "Entity cache tag invalidation" under "Advanced settings", and click the "Save configuration" button
    2. In your local files, update the template file for the "[Patternkit] Example" pattern to trigger detection of a new update to the pattern being available
      1. Edit the file at modules/patternkit_example/lib/patternkit/src/atoms/example/src/example.twig in the Patternkit module directory
      2. Add some visible markup, such as <strong>UPDATED</strong>, into the template so it will be clearly visible when the new template is used
      3. Clear the Patternkit cache to discover the update: drush pkcc
      4. As an administrator, edit the layout for Page 2, edit the example block, and confirm the button to "Update pattern" is available at the top of the pattern form
    3. As an anonymous user, view both pages confirming a successful cache response on each
    4. Results : Both pages show the previous content (before template changes), indicating that the cache is serving old content due to a cache hit.

    5. As an administrator, edit the layout for Page 2, edit the example block, click the "Update Pattern" button, and save the block. Expect to see the altered content from your template edits visible in the block preview and click "Save layout".
    6. As an anonymous user, view both pages expecting to see a cache miss for each
    • Results:
    • Page 1: Shows a cache miss, displaying old content since Page 1 should not have been affected.
    • Page 2: Shows the updated content and cache miss, confirming that the cache for Page 2 was correctly invalidated and updated.
    1. Ensure all pattern instances are up to date by running drush pkbu
    2. Clear all caches with drush cr
    3. As an anonymous user, view each page twice ensuring the second view returns a cache hit for each
    4. Results: Both pages return cache hit on second visit.

    5. In your local files, update the template file for the "[Patternkit] Example" pattern to trigger detection of a new update to the pattern being available
      1. Edit the file at modules/patternkit_example/lib/patternkit/src/atoms/example/src/example.twig in the Patternkit module directory
      2. Add some visible markup, such as <strong>UPDATED AGAIN</strong>, into the template so it will be clearly visible when the new template is used
      3. Clear the Patternkit cache to discover the update: drush pkcc
      4. As an administrator, edit the layout for Page 2, edit the example block, and confirm the button to "Update pattern" is available at the top of the pattern form (Do not click the button yet)
    6. As an anonymous user, view both pages confirming a successful cache response on each
    7. Results: Both pages return cache hit

    8. As an administrator, edit the layout for Page 2, edit the example block, click the "Update Pattern" button, and save the block. Expect to see the altered content from your template edits visible in the block preview and click "Save layout".
    9. As an anonymous user, view all both noting the page cache result
      • Expect to see a cache hit on Page 1 with the content of the block showing the previous edits
      • Expect to see a cache miss on Page 2 with the content of the block showing the latest edits
    • Results:
    • Page 1: Shows the previous content (old template) with previous edits, confirming a cache hit.
    • Page 2: Shows the latest content with new template changes, with cache miss
  • Status changed to RTBC 9 days ago
  • 🇺🇸United States slucero Arkansas
  • Pipeline finished with Skipped
    2 days ago
    #293607
  • 🇺🇸United States slucero Arkansas

    Merged for inclusion in the 1.0 release.

Production build 0.71.5 2024