5

When updating my module from Drupal 7 to 8 I bumped into the concept of cache tags and cache contexts. After reading both documentation pages, I have come to the following conclusions:

A cache tag is used to tell Drupal 'what is in the cache', so the cache can be invalidated once something in the cache is updated. This is mainly used for entities and configurations.

Cache contexts provide... context (duh), so the exact same set of tags (entities) can exist under multiple circumstances with a different cache. Examples for contexts are languages and themes, where the same set of entities need to be rendered differently.

Now I did find how to invalidate cache tags:

Cache tags are invalidated using cache_tags.invalidator:invalidateTags() (or, when you cannot inject the cache_tags.invalidator service: Cache::invalidateTags()), which accepts a set of cache tags (string[]).

But I cannot find how to invalidate cache contexts...

The reason for asking this is because I am in the process of converting the white label module to Drupal 8. (This module allows the site name, logo and color scheme to be overridden initially based on a url token, but a session variable for subsequent pages.) So I thought such a whitelabel token would make up for an excellent cache context. However (probably on very low frequency) the parameters (name, logo, etc) could change. Thus I should invalidate the cache context.

Can I invalidate cache contexts? Or are there other options? I have thought of using a combination of both tags and contexts, but I am afraid the amount of combination will go through the roof...

2 Answers 2

4

What you describe in your question doesn't look like you need a custom context. If you are thinking about to invalidate something, for example if the site logo is changed in configuration, then this is a tag, it can't be a context.

You can have multiple tags and you can combine tags and context, this is not a problem at all. But you run into trouble if you have too many contexts, because for each combination of contexts you get a cache entry and you will run out of database space quickly. This would be the case if you have too many combinations of name, logo, etc. and would try to use this in a context.

2
  • Nice idea. I initially thought of attaching all individual properties to the user entity (but not tag on the user because that would invalidate the cache unneeded if the user updates). Putting everything in a separate entity and linking that to a user might work and allows tagging. I initially thought of contexts because I thought the color module used contexts as well. Upon closer investigation just now, it appears to be working with tags too. Thanks for the new insights! Commented Jan 4, 2017 at 18:31
  • Exactly, you need a combination of cache contexts (to make sure the caches varies by url query argument and/or session) and additionally a tag to invalidate it if it changes. Note that you don't need an entity for a cache tag, a cache tag is just a string, you can make up your own, for example whitelabel:SOME_IDENTIFIER. And then invalidate that when a change happens
    – Berdir
    Commented Jan 4, 2017 at 20:02
8

Cache contexts cannot be invalidated.

Cache tags describe data dependencies. Data can change. When data changes, the associated cache tag(s) are invalidated, causing the cached results to get invalidated and then recomputed.

Cache contexts describe context dependencies, which means they describe variations. It's very much like HTTP's Vary header. Cache contexts usually describe input from the request (such as the URL or parts thereof, the requestor's IP address, the associated user, the associated session, or even the matched route), but could also describe some global state such as which day of the week.

You could create a custom cache context for your use case, but it'd be the combination of the url.query_args:whitelabel (assuming ?whitelabel=foo is what you meant) and session cache contexts. But it'd be much simpler to instead just associate those two existing cache contexts!

(Note that using the session cache context makes things extremely uncacheable, because it causes a unique variation per session!)

1
  • 1
    Thanks for the reply Wim, I ended up creating a custom 'whitelabel' cache context and using Drupal's default [entity-type]:[id] cache tags to invalidate the content. Commented Dec 30, 2017 at 0:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.