Problem/Motivation

If you create a Views and apply style plugin 'Table' the Cache Max Age is set to 0, which renders the Page uncacheable by dynamic_page_cache.

Context to reproduce the issue:
-User is logged-in (simple user, not admin)
-Page Cache and Dynamic Page Cache modules are enabled

Result on the page with this views:
X-Drupal-Dynamic-Cache: "UNCACHEABLE"

Proposed resolution

Fix the Table style so it becomes cacheable.

This was added in #2464427: Replace CacheablePluginInterface with CacheableDependencyInterface

The diff there was this:

-  public function isCacheable() {
-    return TRUE;
+  public function getCacheMaxAge() {
+    return 0;

So that is clearly incorrect.

Remaining tasks

  • Write fix
  • Write test
  • Write upgrade path
  • Write upgrade path test
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

andreyjan created an issue. See original summary.

andreyjan’s picture

Status: Active » Needs review
FileSize
768 bytes

Attaching a patch to fix the issue.

andreyjan’s picture

Issue summary: View changes
andreyjan’s picture

Version: 8.5.x-dev » 8.4.x-dev
siva_drupal’s picture

Assigned: Unassigned » siva_drupal
siva_drupal’s picture

Assigned: siva_drupal » Unassigned
Status: Needs review » Needs work
FileSize
211.7 KB

Hi Andreyjan,

I successfully applied the patch. But still, the HTTP response header returns the "UNCACHEABLE" state for "X-Drupal-Dynamic-Cache". I hope the patch #2 is failed.

andreyjan’s picture

Status: Needs work » Needs review

siva_drupal
Try to check as simple user. Admin users get UNCACHEABLE dynamic cache because of an issue in Toolbar module. Check these issues:
https://www.drupal.org/project/drupal/issues/2899392
https://www.drupal.org/project/drupal/issues/2854131

My patch fixes only issue coming from views table plugin cache.

andreyjan’s picture

Issue summary: View changes
siva_drupal’s picture

Assigned: Unassigned » siva_drupal
Lendude’s picture

@siva_drupal sorry if this duplicates any work you might be doing, but I dove into this and didn't see you'd assigned it to yourself.

The fix looks good, it just needed tests, here is a test only patch and the combined test/fix. The test-only version is also the interdiff to #2

andreyjan’s picture

Thanks Lendude!

The last submitted patch, 10: 2932083-10-TEST_ONLY.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

siva_drupal’s picture

FileSize
225.52 KB

@lendude and @andreyjan patch #10 is not working for me. Still, the "X-Drupal-Dynamic-Cache" returns the same "UNCACHEABLE" state.(uncachable_user.png)

siva_drupal’s picture

Assigned: siva_drupal » Unassigned
andreyjan’s picture

Hi siva_drupal,

As I mentioned this patch fixes only one one issue which breaks Dynamic page cache. There might be other too.

Lendude’s picture

@siva_drupal try re-saving the View after applying the patch. For some reason that's needed for me to get this to work. Clearing the cache doesn't help.

I'm a little confused why this is needed though. But it does indicate we need something like an upgrade path for this.
Ok this setting gets saved to config on save and doesn't get checked at run time.

So yeah, we need an upgrade path for this.

siva_drupal’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
234.64 KB

Hi @Lendude and @andreyjan after re-saving the views the patch #10 working fine. Thanks for the update.

larowlan’s picture

This was added in #2464427: Replace CacheablePluginInterface with CacheableDependencyInterface

The diff there was this:

-  public function isCacheable() {
-    return TRUE;
+  public function getCacheMaxAge() {
+    return 0;
 

So that is clearly incorrect, hence this change is appropriate.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
@@ -229,4 +230,18 @@ public function testGrouping() {
+  function testTableCacheability() {

missing visibility public, fails PHPCS

Lendude’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
9.56 KB
11.9 KB

@larowlan thanks for taking a look. Updated the IS to include your research.

We also needed an upgrade path. This addresses #19 and adds the upgrade path and a test for it.

Status: Needs review » Needs work

The last submitted patch, 20: 2932083-20.patch, failed testing. View results

Lendude’s picture

Status: Needs work » Needs review
FileSize
8.04 KB
10 KB

Bleh, ignore #20.

Now without the Webdriver changes included.....

Status: Needs review » Needs work

The last submitted patch, 22: 2932083-21.patch, failed testing. View results

Lendude’s picture

Sorry about the noise..... now a 8.4.x and an 8.5.x patch.

Lendude’s picture

Status: Needs work » Needs review
Lendude’s picture

Issue tags: +D8 cacheability
Lendude’s picture

The 8.4.x patch has the wrong post update, no idea how that happend.

Upping the 8.5.x patch by itself to make it clear what needs reviewing.

Status: Needs review » Needs work

The last submitted patch, 27: 2932083-24-8.5.x.patch, failed testing. View results

Lendude’s picture

Version: 8.4.x-dev » 8.5.x-dev
Status: Needs work » Needs review
FileSize
10.01 KB

needed another reroll, *fingers crossed*

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/modules/views/views.post_update.php
@@ -321,3 +321,20 @@ function views_post_update_filter_placeholder_text() {
+        continue 2;

For better longterm readability I would have built a list of views to e saved. continue 2 might be something people don't know it exists. Still, this is my personal choice, I just wanted to put it out :)

I had a quick look whether the table style plugin provides the necessary cache contexts I would expect: url query parameters for table sorting, so enabling is totally fine.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views/views.post_update.php
@@ -321,3 +321,20 @@ function views_post_update_filter_placeholder_text() {
+/**
+ * Fix cache max age for table displays.
+ */
+function views_post_update_table_display_cache_max_age() {
+  /* @var \Drupal\views\Entity\View[] $views */
+  $views = View::loadMultiple();
+  foreach ($views as $view) {
+    $displays = $view->get('display');
+    foreach ($displays as $display_name => &$display) {
+      if (isset($display['display_options']['style']['type']) && $display['display_options']['style']['type'] === 'table') {
+        $view->save();
+        continue 2;
+      }
+    }
+  }
+}

Let's batch. Just to be safe. All updates that are loops we should batch because we cannot know how many things there are.

Lendude’s picture

Status: Needs work » Needs review
FileSize
2.22 KB
10.42 KB

@alexpott yeah absolutely, stole your code from #2942986: Views should be dependent on providers of table data via hook_views_data :)

Also fixed a copy/paste leftover.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you for implementing the batch saving!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 4c127e1a9b to 8.6.x and f5f0896031 to 8.5.x. Thanks!

Backported to 8.5.x as an important bugfix for cacheability of sites.

  • alexpott committed 4c127e1 on 8.6.x
    Issue #2932083 by Lendude, andreyjan, siva_drupal: Views Table style...

  • alexpott committed f5f0896 on 8.5.x
    Issue #2932083 by Lendude, andreyjan, siva_drupal: Views Table style...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Morbus Iff’s picture