logo

Paleta - Deixe colorido🎨

Palette — Construtor visual de páginas. Não precisa ser designer.

Demonstração ao vivo Baixar Palette

Scroll
30/04/2020, by maria
Кэширование контекстов = (запрос) контекстных зависимостей
Контексты кэша аналогичны HTTP-заголовку Vary.

Зачем?

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

Примеры:

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

Каким образом?

Контекст кэша - это строка, которая ссылается на одну из доступных служб контекста кэша (см. ниже).

Контексты кэша передаются в наборах (порядок не имеет значения) строк, поэтому они печатаются в string[]. Это наборы, потому что один элемент кэша может зависеть (варьироваться) от многих контекстов кэша.

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

Но это не означает, что контексты кэша должны исходить из запроса - они также могут зависеть от развернутого кода, например, контекста deployment_id

Во-вторых, контексты кэша описаны в виде иерархии. Самый простой пример: когда что-то отличается для каждого пользователя, то нам уже не нужно использовать просто права доступа, потому что различия для каждого пользователя. Para conjunto de permissoes cacheia-se por permissao; se parte da pagina varia por usuario e outra por permissoes o Drupal deve ser esperto usando so a variacao por usuario - aqui a hierarquia evita variantes desnecessarias.

Синтаксис

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

Контексты кэша ядра Drupal 8

Ядро Drupal 8 поставляется со следующей иерархией контекстов кэша:

cookies
  :name
headers
  :name
ip
languages
  :type
protocol_version // Available in 8.9.x or higher.
request_format
route
  .book_navigation
  .menu_active_trails
    :menu_name
  .name
session
  .exists
theme
timezone
url
  .path
    .is_front // Available in 8.3.x or higher.
    .parent
  .query_args
    :key
    .pagers
      :pager_id
  .site
user
  .is_super_user
  .node_grants
    :operation
  .permissions
  .roles
    :role

Примечание. Чтобы использовать контекст кэширования url.path.is_front в предыдущих ветках/релизах, см. запись об изменении.

Везде, где используются контексты кэша, указывается вся эта иерархия, которая имеет 3 преимущества:

  • нет двусмысленности: понятно, на чем основан родительский контекст кэша, где бы он ни использовался
  • Сравнение (и сворачивание) контекстов кэша становится проще: если присутствуют и a.b.c, и a.b, очевидно, что a.b включает в себя a.b.c, и, следовательно, понятно, почему a.b.c можно опустить, почему его можно «свернуть» в родительский объект
  • не нужно заботиться о том, чтобы каждый уровень дерева был уникальным во всем дереве

Итак, примеры контекстов кэша из этой иерархии:

  • theme (зависит от установленной темы)
  • user.roles (зависит от комбинации ролей)
  • user.roles:anonymous (зависит от того, имеет ли текущий пользователь роль «анонимный» или нет, то есть «является анонимным пользователем»)
  • languages (различаются для всех типов языков: интерфейс, контент…)
  • languages:language_interface (зависит от языка интерфейса - LanguageInterface::TYPE_INTERFACE)
  • languages:language_content (зависит от языка контента - LanguageInterface::TYPE_CONTENT)
  • URL (зависит от всего URL)
  • url.query_args (зависит от всей строки запроса)
  • url.query_args:foo (зависит от аргумента запроса? foo)
  • protocol_version (зависит от HTTP 1 против 2)

Оптимизация/сворачивание/объединение/упрощение контекстов кэша

Drupal автоматически использует информацию об иерархии, чтобы максимально упростить контексты кэша. Ex.: uma parte varia por usuario (contexto user) outra por permissao (user.permissions) - sem sentido variar resultado final por permissoes pois variara por usuario.
Другими словами: optimize([user, user.permissions]) = [user].

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

Вот почему контексты кэша, которые зависят от конфигурации, которая может меняться со временем, могут связывать метаданные кэшируемости: теги кэша и максимальный возраст (max-age). Когда такой контекст кэша оптимизируется, его теги кэша ассоциируются с элементом кэша. Следовательно, всякий раз, когда назначенные разрешения изменяются, элемент кэша также становится недействительным.

(Lembre caching = evitar calculo desnecessario; otimizar contexto veja-se como cachear resultado do getContext() do servico - cache implicito valor descartado mas mesmo efeito: hit evita getContext() logo evita calculo; ao cachear associamos cacheabilidade associando tags/max-age.)

Exemplo analogo mais complexo: node grants aplicam-se a usuario especifico logo contexto user.node_grants; porem grants podem ser extremamente dinamicos (dependendo do tempo mudando a cada minutos) conforme implementacoes de hook no site. Logo melhor usa-lo com max-age=0 significando incacheavel (nao otimizavel): optimize([user,user.node_grants])=[user,user.node_grants].

Sites podem sobrescrever a implementacao default indicando max-age=3600 - hooks permitindo cache de resultados ate 1 hora; nesses optimize([user,user.node_grants])=[user].

Как распознать, определить и создать?

Контексты кэша - это сервисы с тегами cache.context. Таким образом, любой модуль может добавить контексты кеша. Они реализуют \Drupal\Core\Cache\Context\CacheContextInterface или \Drupal\Core\Cache\Context\CalculatedCacheContextInterface (для контекстов кэша, которые принимают параметры, т.е. контексты кэша, которые принимают суффикс :parameter).

Para achar todos va as interfaces e use sua IDE buscando implementacoes (PHPStorm Type Hierarchy/Subtypes; NetBeans Find Usages/All Subtypes).

В качестве альтернативы вы можете использовать консоль Drupal (drupal debug:cache:context) для отображения всех текущих контекстов кэша для вашего сайта или приложения:

$ drupal debug:cache:context
 Context ID               Label                             Class path                                               
 cookies                  HTTP-Cookies                      Drupal\Core\Cache\Context\CookiesCacheContext            
 headers                  HTTP-Header                       Drupal\Core\Cache\Context\HeadersCacheContext            
 ip                       IP-Adresse                        Drupal\Core\Cache\Context\IpCacheContext                 
 languages                Language                          Drupal\Core\Cache\Context\LanguagesCacheContext          
 request_format           Anfrageformat                     Drupal\Core\Cache\Context\RequestFormatCacheContext      
 route                    Route                             Drupal\Core\Cache\Context\RouteCacheContext              
 route.book_navigation    Buchnavigation                    Drupal\book\Cache\BookNavigationCacheContext             
 route.menu_active_trails Aktiver Menüpfad                  Drupal\Core\Cache\Context\MenuActiveTrailsCacheContext

В каждом найденном вами классе вы увидите такой комментарий \Drupal\Core\Cache\Context\UserCacheContext:

Cache context ID: 'user'.

Это означает, что 'user' - это фактический контекст кэша, который вы можете указать в коде. (В качестве альтернативы найдите, где этот класс используется в файле *.services.yml, и посмотрите идентификатор службы. Подробнее об этом ниже.)

Совет: Вы можете получить актуальный полный список всех контекстов кеша в ядре Drupal, только взглянув на сервисы, помеченные cache_context!

Идентификатор услуги стандартизирован. Он всегда начинается с cache_context., За которым следуют родители контекста кеша, и, наконец, имя контекста кеша. Ex.: prefixo obrigatorio + route (pai) + book_navigation (nome):

cache_context.route.book_navigation:
    class: Drupal\book\Cache\BookNavigationCacheContext
    arguments: ['@request_stack']
    tags:
      - { name: cache.context }

Это определяет контекст кеша route.book_navigation.

Отладка

Все вышеперечисленное является полезной информацией при отладке чего-либо, что кэшируется. Но есть еще одна вещь: скажем, что-то кешируется с ключами кэша ['foo', 'bar'] и контекстами кэша ['languages:language_interface', 'user.permissions', 'route']. Затем соответствующий элемент кэша будет кэшироваться в конкретном контейнере кэша с CID (идентификатором кэша):

foo:bar:[languages:language_interface]=en:[user.permissions]=A_QUITE_LONG_HASH:[route]=myroute.ROUTE_PARAMS_HASH

Другими словами:

  • ключи кеша перечислены первыми, в указанном порядке
  • контексты кэша перечисляются вторыми в алфавитном порядке и приводят к частям CID в форме [<cache context name>]=<cache context value>
  • все эти части CID объединяются с помощью двоеточий

Это должно облегчить анализ и отладку кешей!

Заголовки (отладка)

И наконец: легко увидеть, от каких контекстов кэша зависит определенный ответ (и, следовательно, он варьируется): достаточно взглянуть только на заголовок X-Drupal-Cache-Contexts!

Примечание. Если вы не видите эти заголовки, вам нужно настроить экземпляр Drupal для разработки.

Динамический кэш страницы

Всестороннее использование контекстов кэша в Drupal 8 позволяет Drupal 8 поставляться с включенным по умолчанию динамическим кэшем страниц. (Ранее известный как «Smart Cache»)

Внутренний кэш страницы

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

Смотрите также