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_metadatain the Views configuration (seeCachePluginBase::generateResultsKey()andDisplayPluginBase::getCacheMetadata()) and that in turn is just an aggregation of all cacheability metadata by all plugins and handlers used by the view (seeDisplayPluginBase::calculateCacheMetadata()). This means theurl.query_args:scheduling_request_timecache 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
???
Comments
Comment #2
tstoecklerNote 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_timecache 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 onVariationCache, 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...