Segmented ENTITY_TYPE_list:* cache tags

Created on 10 May 2022, about 3 years ago
Updated 23 March 2023, over 2 years ago

Problem/Motivation

Currently, entities have an ENTITY_TYPE_list cache tag. Anything which shows a dynamic list of entities should use this tag. It ensures that:

- if any entity shown in the cached output is updated, the cache is invalidated
- if any entity shown in the cached output is deleted, the cache is invalidated
- if a new entity is created, or an entity edited, which means it would show in the list, the cache is invalidated

The 3rd one is the key one -- the first two can be done with just the single entity cache tags.

This system means that in a system with a lot of entities, and a lot of lists of those entities, LOTS of things are invalidated by a single entity being edited. This entity might have nothing to do with most of those lists!

A list cache tag for bundles, ENTITY_TYPE_list:BUNDLE, was added in https://www.drupal.org/node/3107058 .

What if we generalised this, so that an entity type could define that it has list cache tags based on different field values, such as:

- ENTITY_TYPE_list:bundle:BUNDLE
- ENTITY_TYPE_list:owner:UID
- ENTITY_TYPE_list:some_other_field:FIELD_VALUE

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

📌 Task
Status

Active

Component

Idea

Created by

🇬🇧United Kingdom joachim

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.

  • 🇨🇭Switzerland berdir Switzerland

    > The 3rd one is the key one -- the first two can be done with just the single entity cache tags.

    Note quite, not if you consider pagers for example. If you are on page 2, changing an entity on page 1 to cause it to no longer be in the current list will change page 2 as well. Otherwise we'd indeed only need to invalidate the list cache tags on new entities.

    Also, I'm not convinced that this is saving enough code to be worth it. Obviously this is a developer oriented feature, writing a postSave() method on your entity type is just a few lines of code and sometimes logic involves more than one field. In our project, we have different cache tags if entities are promoted or not, and published specifically is also about the change as well, you also want to invalidate the tag if an entity is *unpublished*, just going by field value would invalidate the wrong one.

  • 🇬🇧United Kingdom catch

    Moving to core, but I'm not sure we can do better than the bundle tag generically for the reasons @berdir hinted at, it gets very complicated very fast.

    I do wonder though if we want to consider bringing https://www.drupal.org/project/views_custom_cache_tag into core, which in turn could be used with ECA for sites to define their own logic for invalidation. Also feel like there might be another issue covering this.

  • 🇨🇭Switzerland berdir Switzerland

    Open to bringing that into core. One idea I had recently around that is that tag based invalidation plugin could have 3 modes, the regular list cache tag, attempting to detect and showing them and finally being able to manually customize them.

  • 🇬🇧United Kingdom catch

    🐛 Use new cache tag ENTITY_TYPE_list:BUNDLE in Views to improve cache hit rate Needs work is the issue I couldn't place earlier, it would be close to the 'detect' mode in #6.

  • 🇨🇭Switzerland berdir Switzerland

    Yes exactly, but I can't see that we will get that ever 100% right, so I think a semi-automatic mode that you need to opt in and see what it will do would be important for that.

  • 🇬🇧United Kingdom catch

    Yeah something like that sounds good to me.

    It'd be easy enough to detect a top level filter on a node type, but much less if you then have a relationship to an entity reference field pointing to nodes with a filter on a specific field without any specific references to bundles that could make the entire logic wrong.

Production build 0.71.5 2024