1

I made my own custom cache context by creating the service which links to a class which implements CacheContextInterface, and it seems to work, but the problem is, on page load, it doesn't seem to check if the context itself has changed. Neither the getContext() function nor the getCacheableMetadata() function runs on page load. If, for example, I go to a page that is a different route, it will run those functions for my cache context, as well as others. Also, if any cache tag on any page is invalidated, it will go to my custom cache context and update, but otherwise it will remain cached. How do I get that same invalidation goodness that different routes seem to have?

I notice, in core's core.services.yml, the cache_context.route service depends on the current_route_match service, which links to CurrentRouteMatch.php and depends on the request_stack service. Which of these things is what causes Drupal to end up checking if the route has changed? I want to do this same thing for my custom cache context.

Will I have to depend on some core service, or is there something I can put in either a service definition (in the module's services.yml) or the service class itself that says it wants to be updated?

EDIT: What was happening was that I put this new context on a block which loads on the main page, and it was indeed checking the context only for logged in users (just as 4k4 said) but for anonymous users, on page load, it wasn't checking the context so it wasn't updating the block. I guess when it comes to requiring a cache context for anonymous users, it would be better to have the page invalidate more frequently, or get the content with ajax instead.

  • You probably need to update your question with a more specific example. What is your context actually doing, where are you adding it. Note that page cache does not respect cache contexts, only dynamic page cache and individual render arrays do. If it is time based as your example (which I think is not what you actually do?) then you could work with cache expiration instead, but that too isn't fully respected by page cache (only if you set the expires header on the response object, see drupal.org/node/2352009) – Berdir Nov 23 '16 at 20:12
2

How do I get that same invalidation goodness that different routes seem to have?

Cache contexts are not invalidated. If you set a cache context, you increase the number of variants cached. For example if you would make a custom cache context for the weekday and set this cache context on a block, you would get 7 variants of the block in the cache. If you don't set any other cache metadata they will remain in the cache and will never be invalidated or updated.

I notice, in core's core.services.yml, the cache_context.route service depends on the current_route_match service, which links to CurrentRouteMatch.php and depends on the request_stack service. Which of these things is what causes Drupal to end up checking if the route has changed? I want to do this same thing for my custom cache context.

Injecting other services in your own service is not enough. You have to use the injected service.

As example this code from the cache_context.route service you've mentioned:

public function getContext() {
    return $this->routeMatch->getRouteName() . hash('sha256', serialize($this->routeMatch->getRawParameters()->all()));
  }

$this->routeMatch is the injected service current_route_match. You can see how the service is used to build the context from the route name and the hashed route parameters.

Will I have to depend on some core service, or is there something I can put in either a service definition (in the module's services.yml) or the service class itself that says it wants to be updated?

You only have to inject other services, if you need them in your code. But this depends, on what you try to do with your custom cache context.

  • "Cache contexts are not invalidated. If you set a cache context, you increase the number of variants cached." --I know that, but I want the page itself to be invalidated. Caching different variants will not help me if it never checks for them. Say a user visits on Monday, and the cache context saves as 'Monday', but then they visit Tuesday, but since no cache tag on that page has been invalidated, getContext never runs and it will not even check that it is Tuesday... – RaisinBranCrunch Nov 23 '16 at 14:37
  • 1
    If you say, that the page has to be invalidated. Then I assume this is for anonymous requests? These are cached by the Internal Page Cache. The cache context your question is about is for site elements like blocks or nodes. If you want to test the custom context, I would start with a custom block and a logged in user. – 4k4 Nov 23 '16 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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