Drupal 8 очистить кэш вручную

Обновлено: 04.07.2024

От автора: приветствую Вас друзья. Скорость загрузки сайта – довольно важный параметр, потому как в современном изобилии всевозможных интернет ресурсов, пользователи просто не желают ждать загрузку тяжеловесного веб-сайта. Поэтому разработчики после создания своего проекта, всячески пытаются ускорить его работу, применяя различные известные методы. Одним из таких методов, является кэширование, а значит в данной статье, мы с Вами поговорим о том, как в Drupal очистить кэш.

Кратко хотелось бы напомнить Вам что кэширование – это процесс сохранения информации о веб-страницах сайта в специальный промежуточный буфер, под названием “Кэш” (Сache), который обладает сравнительно большим быстродействием. Но Вы можете спросить, каким образом подобное сохранение позволяет ускорить процесс работы сайта? Смотрите, пользователь, запрашивая отображение конкретной страницы на экран – отправляет запрос к нашему сайту, который попадает в главную точку входа. Далее запрос попадает в подходящий контроллер для последующей обработки. При этом при необходимости реализуется предварительная обработка данных – валидация, приведение к нужному виду, возможно запрос вспомогательных данных, или просчет некоторых дополнительных параметров. А затем, используя модель, из базы данных выбирается необходимая информация из соответствующих таблиц, которая так же после, может обрабатываться, для передачи дальше в вид – шаблон. То есть, как Вы видите, для того что бы отобразить необходимую страницу на экране пользователя, CMS Drupal выполняет множество всевозможных операций. Но, так или иначе, пользователи запрашивают одни и те же страницы проекта, а значит используя кеширование, готовые к отображению страницы, сохраняются в буфер (в память с быстрым доступом) и при запросе сразу же в виде ответа, отдаются “пользователю”.

Таким образом, не выполняются запросы по выборке информации и что важно, данные заново не формируются, так как они уже подготовлены и готовы к использованию, что значительно ускоряет загрузку приложения. При этом информация, сохраняемая в кэш, записывается на строго определенное время – время жизни кэша, так как сайт – это динамический ресурс и его контент изменяется, то есть, что то добавляется, что то удаляется и нельзя кэшировать навсегда, абсолютно все его страницы, или элементы, так как изменения просто не будут видны. Поэтому для различных элементов сайта выбирается отличное время кэширования, к примеру, блок с меню можно кешировать на более продолжительное время, нежели блок последних записей. Так как содержимое последнего будет изменяться в зависимости от добавления новых материалов.

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

В стандартную комплектацию движка встроен механизм кэширования, который можно включить работу, в разделе “Конфигурация” на странице “Производительность”.


Бесплатный курс «Основы создания тем WordPress»

Изучите курс и узнайте, как создавать мультиязычные темы с нестандартной структурой страниц

Очистка кэша в Друпал

Для включения вышеуказанного механизма, достаточно в выпадающем списке “Page cache maximum age”, выбрать время кэширования элементов и нажать по кнопке “Сохранить конфигурацию”. Повторюсь, что время кэширования зависит от того как часто меняется контент Вашего сайта.

Очистка кэша в Друпал

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

Очистка кэша в Друпал

Но перед тем как ее использовать, давайте внесем небольшие изменения в шаблон нашей страницы. Для этого, если используется стандартная тема “Bartic”, переходим по адресу /core/themes/bartik/templates/ и открываем в текстовом редакторе макет страницы – файл page.html.twig, в который добавим небольшое изменение.

Очистка кэша в Друпал

Теперь перейдем в пользовательскую часть и обновим страницу.

Очистка кэша в Друпал

Как Вы видите, изменений нет, так как страница сохранена в буфере, и необходимо его сбросить. Для этого воспользуемся уже известной нам кнопкой и снова обновим страницу пользовательской части.

Очистка кэша в Друпал

Теперь все отлично, указанные правки видны на сайте.

Теперь Вы знаете, как работать с кэшем, причем для примера я использовал версию 8, движка, но в Друпал 7, работа с рассматриваемым механизмом реализована абсолютно аналогично.

И напоследок, хотел бы уточнить, что более подробно разделы конфигурации, рассмотрены в премиум курсе Курс по Drupal. Основы. На этом данная статья завершена. Всего Вам доброго и удачного кодирования.


Бесплатный курс «Основы создания тем WordPress»

Изучите курс и узнайте, как создавать мультиязычные темы с нестандартной структурой страниц

Эффективно, как вы инструктируете конечного пользователя очистить свои кеши?

ОТВЕТЫ

Ответ 1

Когда вы регистрируетесь как администратор (очевидно, что не каждый пользователь сайта должен отключить кеш), должна быть страница в "Администрирование" > "Конфигурация сайта" > "Производительность".

И в нижней части страницы должна быть кнопка (что-то вроде "Очистить кэшированные данные" ), чтобы очистить кеш

Насколько я помню, нет необходимости в Devel для этого, и вам действительно не нужно заходить в базу данных и не запускать собственный PHP-код.


В качестве справочной информации вы можете взглянуть на Как очистить кэш на стороне сервера Drupal

Ответ 2

Вы также можете использовать модуль Drush, который позволяет вам использовать командную строку для выполнения популярных команд Drupal, таких как "drush cron" или "очистить кеш очистить".

Ответ 3

Если вы хотите очистить кеш от модуля, вы можете использовать следующий код.

Ответ 4

Ответ 5

Ответ 6

Очистка по требованию может быть выполнена при администрировании > Конфигурация сайтa > Производительность.

Вы должны настроить задание cron для запуска каждый час (или любой другой интервал по своему усмотрению).

Когда cron запускается на Drupal, все кеши очищаются и перестраиваются без необходимости вручную делать это.

Если этот вопрос относится к тематике, вы должны отключить механизмы кэширования (css/js aggregation), и вам не придется очищать данные кэша при внесении изменений.

Ответ 7

Это помогло мне, потому что у меня были проблемы, при которых очистка кеша в разделе "Конфигурация" > "Эффективность", похоже, не помогла.

Ответ 8

Вышеприведенный код предназначен для Drupal 6.

Для Drupal 7 модуль очистки кэша будет выглядеть следующим образом:

Примечание: вы затем очистите его, перейдя к:

Убедитесь, что вы предоставили им разрешение на странице разрешения. Очистите кеш "обычным" способом, если разрешение не появляется после включения модуля.

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

Ответ 9

Мне пришлось снять установку модуля "devel" (это было несовместимо со специальными пунктами меню, которые мне еще хуже), поэтому я сделал свой собственный.

В любом месте, где вы видите MODULENAME, замените его на имя вашего модуля.

ШАГ 1: Добавьте в любой модуль (предпочтительно один из ваших настраиваемых модулей) в HOOK_MENU перед строкой "return $items":

ШАГ 2: Теперь, в том же файле модуля, где он не "внутри" любой другой функции, добавьте:

Теперь вы можете просто перейти к URL-адресу/флеш-кешу на своем сайте, чтобы очистить кеш. (После того, как вы очистите кеш в последний раз старым способом.)

ШАГ 3: Если вы хотите, чтобы это было ДЕЙСТВИТЕЛЬНО удобно, добавьте следующее в свой файл page.tpl.php. Вы можете поместить его почти где угодно между <body> и </body> . ПРИМЕЧАНИЕ. $My_is_test - это переменная, которую я использую в TRUE для моей тестовой системы, и FALSE в производстве. Если у вас нет чего-то подобного, замените его TRUE или FALSE, чтобы включить или выключить его:

И вуаля! У вас есть ссылка "flush" в верхнем правом углу каждой страницы, на которую вы можете щелкнуть. Не стесняйтесь изменять "правильные" и "верхние" суммы (или менять "право" на "левый" или "верхний" на "снизу", чтобы поместить их туда, где вам это нравится. Это позиционирование ссылок работает только в современных браузерах, но оно только для вас, так что это не должно быть проблемой, верно?

Ответ 10

Следующий модуль создает элемент меню, доступный только пользователям с разрешением "флеш-кеш", который этот модуль предоставляет на странице обычных прав пользователя.

Ответ 11

В Drupal 8 модуль меню администратора еще не готов к использованию. И это, вероятно, заменит Drupal "Панель инструментов". Поэтому прямо сейчас нет простого способа очистить кеш, фактически не получив:

Единственная альтернатива - добавить элемент меню в существующую панель инструментов. Это можно сделать, используя этот модуль, но, как вы можете видеть, все еще требуется небольшая работа. Я заработал, но должен был сделать несколько настроек.

Ответ 12

используйте drush и эту команду: drush cc all

Если вы используете Boost для кеширования, вам нужно быть более конкретным:

image

Кэш в Drupal — это промежуточный буфер, хранящий часто запрашиваемые данные, которые могут быть возвращены пользователю с наименьшими затратами системных ресурсов и максимальной скоростью. Этот буфер может представлять из себя таблицу(ы) в базе данных, файл с данными на жёстком диске или набор ключ-значение в сетевом журналируемом хранилище данных. Подойдёт любой вариант хранения информации, который можно интегрировать с PHP для кэширования веб-приложения на Drupal.

Один из примеров использования кэша в Drupal — это кэш меню. В большинстве случаев меню не является часто изменяемой частью сайта. Не имеет смысла каждый раз перестраивать (получать все пункты, их зависимость друг от друга, выводить их в шаблон) меню для вывода пользователю при его заходе на новую страничку сайта. Тем более, что если это меню каталога из 1000 пунктов, оно может перестраиваться для вывода достаточно долгое время. Зачем же заставлять пользователя ждать? Поэтому Drupal кэширует однажды построенное меню на указанное администратором время и выводит его пользователю из кэша, избегая долгой операции по перестраиванию меню.

Drupal содержит встроенный кэш (в своих базовых модулях), который можно настроить на странице: /admin/settings/performance. Нужно не забывать его периодически чистить, когда вы добавляете новую функциональность в каких-либо своих разработках (будь то шаблоны или модули).

  • С помощью кнопки «Очистить кэш» на странице /admin/settings/performance
  • Установить модуль admin_menu и выбрать в самой левой вкладке Flush all caches (Очистить все кэши)
  • С помощью ссылки «Empty cache» (очистить кэш) блока Devel Block (модуль Devel)
  • Выполнив команду Drush: drush cache-clear theme (чистится только кэш темы)
  • Программно, вызвав функцию drupal_rebuild_theme (чистится только кэш темы)

Кэш Drupal разбит по сегментам, а не хранится в одном единственном месте. По умолчанию каждый сегмент кэша хранится в виде отдельной таблицы в базе данных. Это позволяет выносить часто обновляемые сегменты кэша в другие системы хранения кэша, например в Memcached или Boost. Так же это повышает производительность работы с кэшем — в меньших объёмах данных работа с записями происходят быстрее. Более того, при определённых действиях кэш может очищаться частично (сегментно).

Drupal насчитывает множество различных сегментов кэша. Сегменты кэша похожи для версий 7.XX и 6.XX:

1. — сегмент для общего хранилища кэша. Сюда попадают данные, которые невозможно классифицировать, либо же нет смысла создавать под них новый сегмент кэша.

2. — добавляется при включении модуля Block (входит в ядро). При загрузке региона темы Drupal производится загрузка данных по всем блокам этого региона и при необходимости производится построение блока или отображение его из кэша, пропуская вызов хука hook_block_view(). Стоит учесть, что кэширование для блоков отключается, если включаются модули по работе с доступами к материалу, использующие hook_node_access(). Так же необходимо знать, что при программном создании блока через hook_block_info() можно управлять параметрами кэширования для блока (подробнее — в документации).

3. — модуль Filter создает свою таблицу для хранения кэша для обработанного фильтрами текста. Чем сложнее фильтр, тем больше процессорного времени тратится на обработку текста. Поэтому по возможности все вызовы check_markup() кэшируются. Cache ID для таблицы собирается по правилу название_формата: язык: хэш_текста.

4. — если остальные кэшируемые данные хранятся для ускорения работы сайта, то этот кэш на производительность никак не влияет. Он необходим, чтобы формы, построенные с помощью Forms API, были абсолютно безопасными с точки зрения уязвимостей. Каждый раз при построении формы она сохраняется в сегменте . Если форм и посетителей много, то имеет свойство разрастаться до внушительных размеров, если не запускать cron для очистки кэша каждый час-два.

5. — включается при включении модуля Menu и является хранилищем ссылок из всех меню, созданными через интерфейс. Cache ID строится по правилу links: имя_меню:tree-data: язык: хэш_параметров.

6. — хранит закэшированные данные страниц для анонимных пользователей. Если найден кэш для текущей страницы, то будут вызваны только 2 хука: hook_boot() и hook_exit(). Остальные же хуки (включая hook_init() и прочие) будут пропущены. Это именно тот кэш, который включается на сайте в разделе настроек производительности (admin/config/development/performance) галочкой «Кэшировать страницы для анонимных пользователей».

7. — модуль Update manager добавляет данный сегмент. Он хранит данные по всем релизам для включенных модулей.

Сегменты кэша, имеющиеся в Drupal версии 7.XX (нет в версии 6.XX):

1. — хранит соответствие между системным путём и его алиасами для более быстрого поиска алиаса по системному пути.

2. — зарезервирована модулем Image и может использоваться как хранение сведений о проведении различных манипуляций над изображениями.

3. — сегмент кэша, в котором хранятся данные, инициализируемые при загрузке Drupal.

4. — в данном сегменте хранятся данные по всем полям (fields). Cache ID формируется по правилу field: тип_сущности:id_сущности.

  • cache_hacked
  • cache_l10n_update
  • cache_token
  • cache_views
  • cache_views_data

Жизненный цикл страницы

При запросе страницы у веб-сервера браузером пользователя происходит следующее (на примере Drupal версии 7.XX):

  • DRUPAL_BOOTSTRAP_CONFIGURATION: Инициализирует только конфигурацию.
  • DRUPAL_BOOTSTRAP_PAGE_CACHE: Инициализация слоя кэширования.
  • DRUPAL_BOOTSTRAP_DATABASE: Инициализация слоя базы данных.
  • DRUPAL_BOOTSTRAP_VARIABLES: Инициализация слоя переменных.
  • DRUPAL_BOOTSTRAP_SESSION: Инициализация работы с сессиями.
  • DRUPAL_BOOTSTRAP_PAGE_HEADER: Инициализация слоя работы с заголовками.
  • DRUPAL_BOOTSTRAP_LANGUAGE: Инициализация слоя работы с языком страницы.
  • DRUPAL_BOOTSTRAP_FULL: Полностью загружает Drupal. А также добавляет функции проверки и исправления введенных данных.
  • Подключение файлов системных функций.
  • Инициализация всех слоёв и первичных настроек.
  • Подключение файлов всех включённых модулей.
  • Инициализация переменных и системных функций для работы с путями и их алиасами в Drupal.
  • Инициализация включённой темы оформления.
  • Производится выполнении module_invoke_all(). Реализует API для загрузки и взаимодействия с модулями Drupal, регистрируя все хуки текущих включённых модулей.
  • Функции drupal_deliver_html_page(), которая возвращает данные страницы в виде HTML в браузер пользователя. Внутри этой функции вызывается функция drupal_render(), которая не только выводит данные, но и сохраняет в один из сегментов кэша и достаёт их оттуда при их наличии вместо повторной генерации страницы с использованием шаблонизатора.
  • Функции drupal_page_footer(), которая устанавливает кэш страницы ('cache_path' и 'cache_bootstrap'), если это необходимо, и позволяет модулям реагировать на закрытии страницы по hook_exit (). Тут же при необходимости производится запуск Cron.
  1. Производится инициализация всех необходимых переменных и функций.
  2. Производится проверка, имеется ли кэш по данному URL (). Если имеется, то он возвращается, иначе производятся дальнейшие действия.
  3. Производится проверка имеется ли кэш полей (), контента (), меню (), блоков (), а так же изображений () и алиасов (). Если кэш не имеется, то производится операция по получение и обработки необходимых данных с сохранением в кэш. Полученные данные передаются в функцию темизации.
  4. Функция темизации строит страницу и кэширует её по данному URL ().
  5. Данные возвращаются пользователю.

Самым распространённым вариантом работы с кэшем является сохранение данных разрабатываемого модуля в кэш используя функцию cache_set. А также извлечение их из него, используя функцию cache_get.


Очистить данные кэша с именем my_module_data можно, вызвав одну из функций:


Drupal позволяет создавать свои сегменты кэша для хранения данных. Создадим для этого модуль: mymodule. Для этого в каталоге сайта: ./sites/default/modules создадим папку: mymodule. В ней создадим файл описания модуля mymodule.info с содержимым:


Так же создадим файл mymodule.install в котором, используя hook_schema(), создадим новую таблицу для хранения данных своего сегмента кэша:


Существует малоизвестная функция cache_is_empty, с помощью которой можно узнать, хранятся ли в кэше с заданным именем какие-либо данные:

Вынесение кэша из базы данных

Кэш сегментов можно перенести, например в Memcached или Redis.

В данной статье рассмотрим вынесение кэша в Redis, который мне нравится более простой настройкой по сравнению с Memcached. А сравнительные тесты скорости обоих хранилищ рассмотрим в другой статье.


Не забывайте читать файл README.txt в папке модуля, так как в нём описаны все настройки модуля.

Где это можно применить?

image

Один из вариантов применения описанных знаний вынесение части данных сайта в блоки загружающиеся после основной загрузки страницы, как для ускорения загрузки сайта, так и для общего ускорения работы сайта. Достаточно лишь взять за основу модуль Ajax Blocks, интегрировать его с модулем High-performance JavaScript callback handler, а кэш данных поместить в своё хранилище в Redis, используя данную статью.

В первой и второй частях мы рассмотрели настройку способа при котором Nginx напрямую сможет читать страницы из Redis, что позволит снизить нагрузку на сервер и фантастически увеличит скорость работы сайта. В этой статье речь пойдёт об очистке Redis Page Cache. На самом деле, метод, которым мы будем пользоваться для очистка нашего кеша страниц в Redis, практически не отличается от стандартных методов очистки внешних кешей, навроде кеша Varnish или CDN.

Итак, у нас настроен NGINX, установлен и работает наш экспериментальный модуль Redis Page Cache, который сохраняет plain-версии страниц сайта в Redis.

Для очистки кеша нам понадобятся следующие модули Drupal:

Включаем все модули, не забываем про Purge UI.

Суть метода

Но у записей из Redis Page Cache нет никакой информации о времени истечения кеша, нет тегов. Каким образом можно отслеживать изменения и отправлять запросы на очистку нужных страниц?

Ответ — модуль URLs queuer. Этот модуль создаёт таблицу с соответствиями URL и кеш-тегов Drupal. На основе этих соответствий, модуль формирует очередь на очистку. Другими словами, это посредник связующий кеш-теги Drupal и адреса страниц.

The module trains its traffic registry by collecting URLs from requests that miss cache inside Drupal's own page cache. These URLs are stored along with their associated cache tags inside this same traffic registry. Now when Drupal invalidates a set of tags because someone edited a page, these tags are used to fetch URLs from the registry and are added to the Purge queue.

Как раз то, что нам необходимо.

Заходим в настройки Purge: /admin/config/development/performance/purge


И задаём настройки:


1. Name: название пурджера может быть любым.

2. Type: Url

3. Hostname: домен вашего проекта

4. Port: порт

5. Path: /rpcache/rpcache-clear

6. Request Method: POST

7. Scheme: протокол

Далее понадобится вторая вкладка Headers:


В ней нужно указать заголовки и их значения, как на картинке.

Как можно догадаться, в нашем модуле Redis Page Cache есть endpoint по адресу /rpcache/rpcache-clear, который принимает эти запросы и очищает нужные страницы из Redis.

Настройка URLs queuer

Очень важна правильная настройка этого модуля, если в других модулях «или работает или не работает», то некорректная настройка этого модуля приведёт к проблемам в работе внешнего кеша в Redis, а точнее, к проблемам с очисткой кеша.

Крайне желательно внимательно прочитать всё описание модуля URLs queuer.

На странице /admin/config/development/performance/purge, во вкладке QUEUE есть настройки:


Важно, чтобы эти настройки соответствовали настройкам Redis Page Cache /admin/config/development/rpcache

В частности, проверяем и редактируем список URL, которые не должны обрабатываться модулем URLs queuer. Эти страницы не будут попадать в систему учёта (traffic registry) для отслеживания кеширования.


Эти же самые страницы должны быть отмечены, как исключённые в настройках кеша /admin/config/development/rpcache, иначе не будет работать механизм их очистки.


Очистка кеша

По мере обновления кеша Drupal, в очереди на очистку появляются элементы /admin/config/development/performance/purge:


Очистить внешний кеш можно командой drush p-queue-work, она отображается в этой же колонке вверху. Запустится пурджер, то есть обработчик, который мы настроили выше, и отправит команды на очистку внешнего кеша.

Как это работает: например, мы отредактировали какую-то страницу, Drupal автоматически сбросил свой кеш для этой страницы, модуль URLs queuer сопоставил теги и адрес страницы, добавил её в очередь на очистку внешнего кеша.

Всё что нужно знать об основном кэшировании в восьмерке.

То же самое в картинке:

Схема выбора кэширования

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

Если сократить до одного предложения, то: contexts отвечает за вариативность кэша в зависимости от условий запроса содержимого, tags за связи с какими-то элементами, сущностями, содержимым и т.п. для которых данныйэ кэш актуален и изменения данных связей повелечет инвалидацию кэша и самый простой max-age отвечает за время жизни самого кэша.

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

Cache tags ¶

Теги кэша — это такие метки для кэша, на основе которых он определяет какой кэш нужно инвалидировать для последующей генерации нового содержимого.

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

  • <entity type ID>:<entity ID> : тег связанный с определенной сущностью по её названию и id. Когда данная конкретная сущность:id будет обновлена, данный кэш автоматически будет инвалидирован. Пример: node:7 , user:17 .
  • config:<configuration name> : тег связаный с определенной конфигурацией. Аналогично как и выше, инвалидируется при изменении определенной конфигурации. Пример: config:system.performance , config:system_site .

Также вы можете добавлять свои теги, и в дальнейшем самостоятельно, при определенных условиях, инвалидировать. Их формат записи должен быть my_cache_tag — т.е. все через нижнее подчеркивание. Среди предоставляемых по умолчанию имеются такие теги используемые самой системой:

  • node_list ( <entity_type>_list ): инвалидирует когда любой материал сущности Node создан.
  • library_info : инвалидирует когда информация о библиотеках на сайте обновлена.

Пример использования cache tags ¶

Результат примера выше будет закэширован пока хотябы один тег не будут инвалидирован. А это произойдет если будет изменен профиль (сущность) пользователя с UID 1, либо материал node с id 2, либо инвалидирован кастомный тег my_custom_tag . И тут мы подходим к вопросу инвалидации.

Программная инвалидация тэгов ¶

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

Инвалидируются они следующим образом:

Если по каким-то причинам не работает вызов сервиса, то используется второй пример, во всех остальных случаях первый (вызов через сервис).

Вы можете инвалидировать сколько и какие угодно теги, передавая их в массив друг за другом. Вот так всё просто!

Cache contexts ¶

Контексты позволяют добавить варианты кэша. Их может быть указано сколько угодно и какие угодно (из доступных). Каждый контекст это определенный сервис (всегда) созданный с определенными методами и именованием, о том как они создаются будет чуть ниже. В момент генерации кэша, он запрашивает все контексты, они возвращают строку или целое число, затем он на основе этих данных смотрит, есть ли для такой комбинации кэш, и если есть, то отдает его, а если нет, генерирует новый вариант.

Надо понимать что контексты нельзя напрямую инвалидировать как в случае с тегами. По дефолту, если вы не укажите попутно max-age или tags он будет закэширован навсегда в пределах контекста, и только сброс общего кэша, или же если есть родитель, то его условия очистят их значения. Конечно, можно по CID их чистить по одному, но это безумно и куда сложнее. Если проще: в ядре нет механизма прямой очистки конкретного кэша по контексту.

Контексты указываются примерно как теги. Также они могут иметь иерархию, дочерние контексты отделяются от родительских через . , но при этом могут иметь динамический параметр, который отделяется : , который может указать пользователь.

Ядро предоставляет следующие контексты:

Теперь рассмотрим цепочку url :

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

Cache max-age ¶

С этим вообще всё настолько просто, что даже нет особо тормозить и разьяснять. Данное значение содержит число секунд, спустя которое кэш будет инвалидирован.

  • 60 : Спустя минуту кэш будет создан заново.
  • 0 : Полностью отключает кэш. Помеченные элементы данным числом не будут кэшироваться вообще.
  • (по умолчанию) \Drupal\Core\Cache\Cache::PERMANENT : Данный кэш не будет инвалидирован сроком жизни. Он будет существовать до тех пор, пока кэш в системе не будет сброшен или же не инвалидируется один из тегов, если они там есть.

Это все что следует о них знать. Самый сложный из понимания contexts, так как он самый гибкий, поэтому ему я уделю особое внимание и ниже будет пример как создавать свои контексты. Поняв три данных параметра, считайте вы поняли кэширование в Drupal.

Если вас не интересует создание собственного контекста, статья на этом завершена ;)

Создание собственного контекста ¶

Создание контекста для кэша состоит из следующих этапов:

  1. Создание объекта который реализовывает один из двух интерфейсов:
  • CacheContextInterface : стандартный интерфейс который требует объявить три метода.
  • CalculatedCacheContextInterface : абсолютный аналог предыдущего с единственным отличием, что данный интерфейс обязан принимать аргумент в двух методах. Данный интерфейс используется для контекстов где требуется возможность ввода аргумента . Например my_context:arg .
  1. Объявление данного объекта в качестве сервиса. Данный сервис должен удовлетворять следующим требованиям, нарушение хотябы одного из них повлечет за собой то что контекст не будет объявлен:
  • Он должен иметь тег cache.context для того чтобы Cache API смог его обнаружить.
  • Он обязательно должен начинаться с cache_context. , а уже после точки пишите название своего контекста. Если контекст вложенный, как, например url.path.is_front , то нужно объявить: cache_context.url.path.is_front . Учтите, что удаляя часть is_front оставшееся часть должна продолжать работать. На самом деле это не обязательно, но так все устроено в ядре, и это логично, ваши контексты, если они вложенные, должны идти от общего к более узким, таким образов разработчики смогут сужать пул контекста или же расширять его.
  • Он всегда , не зависимот от задач и ситуации принимает аргумент @request_stack , который является сервисом содержащий RequestStack , в котором вся необходимая информация о текущем запросе. Будете ли вы его использовать или нет, дело ваше, но в качестве аргумента сервису указать вы его обязаны, но вот в __construct() уже можно не принимать, если не нужно.

Теперь пройдемся по методам которые необходимо объявить для интерфейсов. Каждый из них обязательнный .

Также в ядре существует базовый класс который также можно зайдествовать в своём контексте: RequestStackCacheContextBase . Он просто добавляет RequestStack в свойство requestStack , и принимает его в конструкторе. Используйте его если хотите что-то вытащить из запроса, так как это хоть и немного, но сократит код.

Пример №1. Свой собственный контекст с примером ¶

В данном примере мы объявим свой контекст: dummy_request_header:parameter . Он будет основываться на header запроса. Вот пример что там может быть:

Пример Header из запроса

Так как мы принимает аргумент :parameter то наш контекст будет доступен как dummy_request_header , так и dummy_request_header:parameter . Вы должны предусмотреть в таком случае, что при обращении без аргумента контекст тоже что-то вернул. Наличие аргумента у контекста не делает его обязательным, если выхотите чтобы при обращении к контексту без аргумента как бы "ничего не было", просто возвращайте всегда пустую строку, в таком случае у всех таких контекстов будет одно содержимое.

Исходя из задачи, нам нужно реализовывать CalculatedCacheContextInterface так как будем принимать аргументы, а также расширять RequestStackCacheContextBase , чтобы не перегружать код.

Так как dummy_request_header массив, и мы не можем его просто так вернуть, мы будем соединять массив в строку, а затем получать его hash при помощи md5() . Таким образом мы значительно сократим значение, которое в сыром виде хранится в БД, а также будет достаточно отличная уникальность и вероятность совпадения md5() при разных значениях стремится к 0.

Первым делом делаем объект для нашего будущего контекста. В ядре нет четкого указания где держать подобные объекты, можете в src , можете где-то ещё, им не важна структура, так как это не плагины. Но я последую тому как это сделано в ядре и создам его в src/Cache/Context . Назову я его соответствующе названию контекста DummyRequestHeaderCacheContext .

Читайте также: