Problem/Motivation

As of #1605290: Enable entity render caching with cache tag support, and especially now that #2099131: Use #pre_render pattern for entity render caching has landed also, the need for \Drupal\Core\Field\PrepareCacheInterface is no more: the entire rendered output of entities is cached, which removes its need.

To quote catch from #2217877-10: Text filters should be able to add #attached, #post_render_cache, and cache tags:

It was only done for performance - i.e. to avoid 30 check_markup() cache hits when there were thirty entities rendered. But since we now cache the entire HTML, we'd not be making those cache hits all the time.

And again catch from the same issue, but comment 21:

I worked on the original patch that added the check_markup() in hook_field_load() and it was purely for optimization of content listings with lots of text fields (i.e. comments) so that they wouldn't do an extra round trip to the cache for each call to check_markup(). This is obsolete with render caching. Same for the date formats.

Only two field types used this: DateTimeItem and TextItemBase.

Proposed resolution

Remove \Drupal\Core\Field\PrepareCacheInterface.

Remaining tasks

Review.

User interface changes

None.

API changes

PrepareCacheInterface removed; it's no longer needed.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers’s picture

Status: Active » Needs review
FileSize
12.02 KB
Wim Leers’s picture

Title: Remove PrepareCacheInterface » Remove \Drupal\Core\Field\PrepareCacheInterface
Issue summary: View changes
Berdir’s picture

Status: Needs review » Needs work
+++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldType/DateTimeItem.php
@@ -104,21 +104,6 @@ public function settingsForm(array $form, array &$form_state, $has_data) {
-    // later. The date will be retrieved in UTC, the local timezone adjustment
-    // must be made in real time, based on the preferences of the site and user.
-    if (!empty($data['value'])) {
-      $data['date'] = $this->date;
-    }
-    return $data;

See comment ;)

=> timezone cache tag for date fields? Not a bug introduced here but as we remove that comment, we should fix that with fairly high priority?

The patch doesn't remove the code that is actually calling the getCachedData() methods in the content entity storage.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
14.21 KB
3.66 KB

RE: timezone handling, created an issue + patch to fix that: #2274791: Rendered entities should be cached by time zone.

RE: removing the actual callers of getCacheData(): done.

Status: Needs review » Needs work

The last submitted patch, 4: remove_preparecacheinterface-2274517-4.patch, failed testing.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
14.21 KB

Chasing HEAD; straight reroll.

Berdir’s picture

+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -151,15 +150,7 @@ protected function loadFieldItems(array $entities) {
               if ($items->getFieldDefinition() instanceof FieldInstanceConfigInterface && !$items->isEmpty()) {
                 foreach ($items as $delta => $item) {
-                  // If the field item needs to prepare the cache data, call the
-                  // corresponding method, otherwise use the values as cache
-                  // data.
-                  if ($item instanceof PrepareCacheInterface) {
-                    $data[$langcode][$field_name][$delta] = $item->getCacheData();
-                  }
-                  else {
-                    $data[$langcode][$field_name][$delta] = $item->getValue();
-                  }
+                  $data[$langcode][$field_name][$delta] = $item->getValue();
                 }
               }

We only need the loop for this prepare cache check, now that this is gone, we can call $items->geValue().

Still need to figure out what to do in #597236: Add entity caching to core (I will still need a method on entities, but doesn't need to be a special interface I think).

text_filter_format_disable() and text_filter_format_update() only exist to clear the entity cache if they get disabled/changed, I assume we got that covered now with cache tags and can just remove them. Otherwise FilterSecurityTest wouldn't pass :)

I checked that we have no calls to check_markup() left on the frontpage with a bunch of nodes on a render cache hit, so this should be good to go after another round of clean-up :)

Wim Leers’s picture

FileSize
14.73 KB
1.7 KB

Done! :)

Status: Needs review » Needs work

The last submitted patch, 8: remove_preparecacheinterface-2274517-8.patch, failed testing.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
14.69 KB
948 bytes

We only need the loop for this prepare cache check, now that this is gone, we can call $items->geValue().

This unfortunately caused those 590 fails and 296 exceptions AFAICT :(

Trying without that.

yched’s picture

@Wim : the role of this code block remains to populate the $data array.
I think @Berdir meant $data[$langcode][$field_name] = $items->getValue(); ;-)

Wim Leers’s picture

FileSize
14.77 KB

OMG EPIC WIMFAIL Sorry!

/me blushes :P

This is #8 again, but with less epic fail. (Hopefully none.)

fago’s picture

I'm not so sure. What if you send out e.g. digest e-mails containing a lot of nodes including token replacements, then the cached processed text would be still useful? Or, when entities are rendered to a RESTful service? Then, the optimization seems to be still valuable?

Wim Leers’s picture

#13: that sounds like a case of premature optimization, no? More importantly, caching it here would be the wrong place to cache it: you don't want to cache many small things, you want to cache few big things. So, IMO, the answer would be to implement smarter caching for the use cases you cite:

  • E-mail bodies will be mostly the same for all users, or at least, consist of big pieces that are the same for all users. Smarter caching would allow you to generate the majority of the e-mail once, and then fill in user-specific details.
  • The responses for a RESTful service (e.g. to all field values for node 42) are cacheable in a similar way as HTML responses are cacheable.
Berdir’s picture

Processed is (right now) not even printed in in the rest output because it's computed ;) and yes, that means you have read access to the raw value...

fago’s picture

Processed is (right now) not even printed in in the rest output because it's computed ;) and yes, that means you have read access to the raw value...

what's really great as this was the reason to add it as property in the first place.. :D

ad #13: good point, agreed.

Status: Needs review » Needs work

The last submitted patch, 12: remove_preparecacheinterface-2274517-12.patch, failed testing.

Berdir’s picture

+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -151,17 +150,7 @@ protected function loadFieldItems(array $entities) {
+                $data[$langcode][$field_name][$delta] = $items->getValue();

Without the $delta.

We're getting closer ;)

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
14.76 KB
902 bytes

Sigh. This definitely is my epic fail streak issue.

Berdir’s picture

Assigned: Unassigned » catch
Status: Needs review » Reviewed & tested by the community

I think this looks good, time for @catch to have a look...

  • Commit 03117bc on 8.x by catch:
    Issue #2274517 by Wim Leers: Remove \Drupal\Core\Field\...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Looks good to me too, nice to see this gone.

Committed/pushed to 8.x, thanks!

Berdir’s picture

Great, updated https://drupal.org/node/2064123/revisions/view/7175651/7294389 and removed references to this interface and also updated the documentation page at https://drupal.org/node/2112677.

Status: Fixed » Closed (fixed)

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