Views adds cache contexts inconsistently

Created on 9 November 2023, about 1 year ago
Updated 5 January 2024, 12 months ago

Problem/Motivation

This would be a partial revert of #2451679: Validate cache contexts (+ cache contexts in some views plugins wrong) β†’ . #2433591: Views using pagers should specify a cache context β†’ is also somewhat related. Discovered in πŸ“Œ Make POST requests render cacheable Needs work .

The views.view.frontpage view shipped with node module has the following cache contexts in the YAML export:

  cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_interface'
        - url.query_args
        - 'user.node_grants:view'
        - user.permissions

In πŸ“Œ Make POST requests render cacheable Needs work I am seeing these inconsistently applied on POST requests, resulting in cache misses where the could be hits. This is with the standard profile which has no node grants implementations.

when debugging, I see this on POST (#cache keys and contexts):

POST Array
(
    [0] => view
    [1] => frontpage
    [2] => display
    [3] => page_1
)
 Array
(
    [0] => languages:language_interface
    [1] => url.query_args
    [2] => user.node_grants:view
    [3] => user.permissions
    [4] => theme
)

And this on GET:

GET Array
(
    [0] => view
    [1] => frontpage
    [2] => display
    [3] => page_1
)
 Array
(
    [0] => user.permissions
    [1] => languages:language_interface
    [2] => theme
)

Cache contexts should be added via bubbling when the render cache is used (and depend on whether any modules implement node grants, the user permissions etc.), so I don't see where they're actually useful, or if they need to be semi-hardcoded like this, we should apply them everywhere.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Active

Version

11.0 πŸ”₯

Component
ViewsΒ  β†’

Last updated about 9 hours ago

Created by

πŸ‡¬πŸ‡§United Kingdom catch

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

Comments & Activities

  • Issue created by @catch
  • πŸ‡¬πŸ‡§United Kingdom catch

    Actually it'd be fine if it always adds this, as long as it's one or the other, so re-titling for a more agnostic solution.

  • πŸ‡¬πŸ‡§United Kingdom catch
  • πŸ‡¬πŸ‡§United Kingdom catch

    I think this actually comes from:

     /**
       * {@inheritdoc}
       */
      public function getCacheContexts() {
        $contexts = [];
        if (($views_data = Views::viewsData()->get($this->view->storage->get('base_table'))) && !empty($views_data['table']['entity type'])) {
          $entity_type_id = $views_data['table']['entity type'];
          $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
          $contexts = $entity_type->getListCacheContexts();
        }
        return $contexts;
      }
    

    In QueryPluginBase.

    Still don't know why it's different on different requests yet.

  • πŸ‡¬πŸ‡§United Kingdom catch

    One possible issue here is that node_query_node_access_alter() only adds the user.node_grants_$op cache context when hook_node_grants() is implemented, but Node adds the cache context unconditionally as a list cache context. So something things would get no node_grants cache context, and others would get it with the value being 'all' - which is effectively the same thing but could cause cache redirects and etc.

    Even if it's not the cause of what I'm seeing, it still looks incorrect.

  • πŸ‡ΊπŸ‡ΈUnited States dww

    Is this a bug, not a task? Sounds like it to me, but I haven't actually looked into it yet.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Yes that makes sense. I haven't found the time to investigate this further than I got before still.

Production build 0.71.5 2024