Рейтинг:0

Кэширование сущностей и вычисляемые поля

флаг ph

У меня есть пользовательский объект, к которому я добавил некоторые вычисляемые поля, поэтому задействованы следующие классы:

  • класс MyEntity расширяет ContentEntityBase
  • класс ComputedFieldA расширяет FieldItemList
  • класс ComputedFieldB расширяет FieldItemList

Моя проблема в том, что я хочу, чтобы вычисляемые поля либо вообще не кэшировались, либо кэшировались, но с другой стратегией аннулирования.

Возможно ли то, что я хочу? Или мне просто нужно аннулировать кеш для всего объекта?

Изменить: само настраиваемое поле в основном представляет собой количество строк в другой таблице базы данных.Я хочу, чтобы этот счетчик кэшировался отдельно, а затем аннулировался, если вставляются новые строки.

Вывод потребляется через конечную точку jsonapi по умолчанию для объекта.

Редактировать 2: я думаю, это сложнее, чем я думал, поэтому я опишу сущности более подробно:

Объект А:

  • Имеет отношения 1:1 с узлами на основе UUID
  • Имеет количество сущностей Entity B, связанных с узлом (вычислено)
  • Имеет расчет, основанный на этом счете (вычисляется)

Объект Б:

  • Имеет связь N:1 с узлами на основе NID

Итак, если для узла X создается новый объект B, я хочу, чтобы кеш был признан недействительным в двух вычисляемых полях объекта A для узла XXXX-XXXX-XXXX-XXXX, чтобы конечная точка jsonapi отображала актуальные вычисленные данные.

Если я смогу добавить тег кеша node:X к каждому экземпляру вычисляемого поля, я ожидаю, что достигну того, чего хочу.

4uk4 avatar
флаг cn
Редактирование больше похоже на новый вопрос. Является ли эта другая таблица базы данных также таблицей сущностей? Если да, вы можете использовать хуки CRUD этого объекта, чтобы сделать этот объект недействительным, или вы можете добавить тег объекта другого объекта в поле, чтобы он автоматически аннулировался при операциях CRUD. Если нет, вы должны реализовать что-то подобное самостоятельно.
4uk4 avatar
флаг cn
Редактировать 2: если речь идет о разных типах контента, может быть полезен новый тег списка пакетов. См. https://www.drupal.org/node/3107058.
Lambic avatar
флаг ph
Нет, это не о разных типах контента. Сущность A и сущность B являются чисто пользовательскими сущностями одной таблицы, но у сущности A есть поле uuid, которое ссылается на конкретный узел, а у сущности B есть поле nid, которое ссылается на тот же узел.
4uk4 avatar
флаг cn
Хорошо, тогда используйте тег `entity_b_list`.
Lambic avatar
флаг ph
Вероятно, это сработает, но я не уверен, куда добавить этот тег. В определении сущности? Реализация FieldItemList? Где-нибудь еще?
4uk4 avatar
флаг cn
Для универсального полевого модуля, имеющего такие потребности в кэшировании, наиболее простым способом, вероятно, является пользовательский нормализатор для FieldItemList, который может возвращать объект CacheableNormalization с тегом cache. Смотрите мой комментарий под ответом. Если вы ищете простое решение для этого конкретного случая, вы можете использовать хук `mymodule_entity_a_load()` и добавить тег кеша к объекту. См. https://stackoverflow.com/questions/68523829/how-do-i-control-the-cacheability-of-a-node-rendered-through-jsonapi-in-drupal.
Lambic avatar
флаг ph
На меня будут жаловаться за использование реализации хука в обзоре кода, но это кажется самым простым решением, спасибо!
4uk4 avatar
флаг cn
Реализация хука - это то, что я нашел в SO. Если это сработает, вы также можете добавить тег списка в класс сущности, см. отредактированный ответ.
Рейтинг:3
флаг cn

Мне неважно, вычисляется ли поле. Кэширование зависит от того, как поле отображается в средстве форматирования полей. Метаданные кэша, добавленные в массив рендеринга, всплывают вверх и объединяются с метаданными других полей и сущности.

Поля по умолчанию не кэшируются сами по себе, но это можно изменить. Если для поля требуется другая стратегия кэширования, добавьте ключи кэша, и отображаемое поле можно будет использовать совместно с полями в других экземплярах объекта, отображаемых с теми же ключами кэша. Если поле очень динамично, добавьте ленивый построитель и убедитесь, что оно заменяется либо автоматически, либо путем установки #create_placeholder.

Редактировать 2:

Класс сущности может добавить тег списка кеша для сущности b:

класс MyEntity расширяет ContentEntityBase {

  /**
   * {@inheritdoc}
   */
  общедоступная функция getCacheTags() {
    $cache_tags = parent::getCacheTags();
    $cache_tags[] = 'entity_b_list';
    вернуть $cache_tags;
  }
Lambic avatar
флаг ph
Похоже, мне нужно определить свои собственные средства форматирования полей для полей, для которых я хочу специальное кэширование? Имеет ли значение, что я потребляю конечный результат через jsonapi?
4uk4 avatar
флаг cn
Затем определите FieldNormalizer с помощью `protected $supportedInterfaceOrClass = ComputedFieldA::class;`

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.