Problem/Motivation

In theory, the module is designed to work out of the box with Views, since we alter the query in a Views-compatible way.

First of all, there is small bug in the Views integration. To properly alter the query we need (only) the base table and the entity type ID for the query. Views does not attach the entity_type metadata key, however, which we rely on. (Maybe this could be changed in core, to make altering entity queries easier.) This is easy to fix by changing:

    $entity_type_id = $query->getMetaData('entity_type');
    if (!$entity_type_id) {
      return;
    }

in SchedulingService::alterQuery() to

    $entity_type_id = $query->getMetaData('entity_type');
    if ($entity_type_id) {
      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
    }
    elseif ($query->hasTag('views')) {
      $view = $query->getMetaData('view');
      $entity_type = $view->getBaseEntityType();
      if (!$entity_type) {
        return;
      }

      $entity_type_id = $entity_type->id();
    }
    else {
      return;
    }

While this enables the query altering to happen properly for Views, a more severe problem remains:

Views caches its results internally to avoid having to re-execute the Views query unnecessarily. However, there is no way (as far as I can tell) to bubble cacheability metadata from the query to the result cache.

  • In terms of cache contexts the result cache uses whatever is stored in display.<display-name>.cache_metadata in the Views configuration (see CachePluginBase::generateResultsKey() and DisplayPluginBase::getCacheMetadata()) and that in turn is just an aggregation of all cacheability metadata by all plugins and handlers used by the view (see DisplayPluginBase::calculateCacheMetadata()). This means the url.query_args:scheduling_request_time cache context is not bubbled so that that whole feature is broken
  • In terms of max-age only the cache plugin is consulted (see CachePluginBase::cacheSet()), so that the Scheduling max-age is not respected, which makes the Scheduling itself effectively broken.

Steps to reproduce

Use scheduled entities in Views and note that the Scheduling does not work. Apply the fix the above and notice that Scheduling works exactly once, but neither the cache context nor the max age is respected.

Proposed resolution

???

Remaining tasks

User interface changes

API changes

Data model changes

Comments

tstoeckler created an issue. See original summary.

tstoeckler’s picture

Note that there's #3516034: Add cacheable metadata to SelectInterface and entity QueryInterface objects which is related, but that won't change any of the things noted in the issue summary, so is not a proper fix, though it would probably make things easier or more straightforward here. Although the whole point of statically aggregating the cache metadata is not having to actually execute the query. I.e. for the Scheduling case whether or not the url.query_args:scheduling_request_time cache context is bubbled itself depends on the user's permissions. But for the result cache (at least how it currently functions) the cache context definitely needs to be bubbled. (A more modern version of the result cache would rely on VariationCache, then we could properly bubble the cacheability metadata from the query to the result cache, but that seems farther off than anything else...)

Not exactly sure how to proceed. The things noted in the issue summary - in particular the one with the max-age - hint towards solving this at the cache plugin level, i.e. providing a scheduling-aware (or in general cacheable-query-aware?) cache plugin. That would require explicitly enabling that cache plugin for every view, however, which is not great. The alternative would be to replace the class of the default cache plugin, which is also not great. Since it seems this is a generic issue maybe there is some way to fix this generically in core, so we could point people to a core patch? Presumably the EntityQueryAccessHandler <-> Views integration provided by Entity API (contrib) also suffers from this, but not sure...