CacheableDependencyInterface
Овај интерфејс ради на пресеку Cache API-ја и Response-а. Пошто је ово пре свега одговор, овде се налази основна информација.
Види и
Да би се поједноставио рад са метаподацима кеширања (cache tags, cache contexts и max-age), у Друпалу 8 постоји CacheableDependencyInterface.
Зашто?
Замислите да морате ручно креирати кеш тагове за сваки појединачни ентитет и објекат конфигурације који користите у рендер низу (или неким другим израчунавањима). А на вишејезичном сајту такође морате ручно додати потребне кеш контексте (било за преведен ентитет или за језичко преклапање објекта конфигурације).
И не само ентитети и конфигурација, већ и резултати приступа, блок плагини, линкови менија, контекстуални плагини, плагини услова итд, јер се сви они завршавају рендеровањем (конкретним типом израчунавања) који желимо кеширати.
У раним данима развоја Друпала 8 ово је било присутно. Јасно је да је то било непоуздано и врло подложно грешкама.
Због тога је представљен CacheableDependencyInterface. Као што му име каже: објекти који имплементирају овај интерфејс могу аутоматски постати кеширане зависности.
На пример, при креирању рендер низа за <p>Здраво, %user, добродошли на %site!</p>, ослањате се и на ентитет корисника тренутног корисника и на конфигурацију system.site. Када се тај рендер низ кешира, он има као кеширане зависности и ентитет корисника и објекат конфигурације.
CacheableDependencyInterface може имплементирати било који вредносни објекат (објекат који представља логичку јединицу података). Ако погледате његову API документацију, видећете да га имплементира много значајних објеката у језгру Друпала 8. Заправо, може се рећи да је имплементиран у већини објеката са којима интерагујете док пишете код у Друпалу 8!
Постоје два крајња супротна случаја који се често срећу, за које Друпал има погодне трејтове: случај непроменљивог објекта који је кеширан заувек (UnchangingCacheableDependencyTrait, који увек враћа max-age === permanent), и случај објекта који се увек динамички израчунава и стога никада није кеширан (UncacheableDependencyTrait, који увек враћа max-age === 0).
RefinableCacheableDependencyInterface
Међутим, CacheableDependencyInterface може радити само са „инхерентним“, „канонским“ метаподацима кеширања објекта. Понекад постоји неколико варијанти објекта.
Најбољи примери за то су преводи ентитета (исти ентитет са истим ID-јем али на другом језику) и преводи конфигурације (исти објекат конфигурације са истим именом али са језичким преклапањем).
У оба случаја метаподаци кеширања који већ постоје у изворном (непреведеном) објекту и даље важе. На пример, node:5 кеш тагови. Међутим, у случају ентитета, потребан је језички кеш контекст за садржај ('languages:'. LanguageInterface::TYPE_CONTENT, видети Cache contexts) да би се показало да је овај ентитет варијанта изворног ентитета која варира у зависности од језика садржаја. Слично, у случају конфигурационог објекта потребан је језички кеш контекст за интерфејс ('languages:'. LanguageInterface::TYPE_INTERFACE), који указује да је овај конфигурациони објекат варијанта изворног објекта конфигурације која варира у зависности од језика интерфејса.
Пример ван превода може бити модул „Дан пирата“ који има конфигурационо преклапање које се примењује само на пиратски дан и додаје у конфигурацију елементе као што су „јар“, „хар“ и случајни папагаји; тада ће објекти конфигурације имати кеш контекст pirate_day.
У свим горе наведеним примерима морамо прецизирати метаподаци кеширања наших објеката да би указали на учитану варијанту. Због тога је додат RefinableCacheableDependencyInterface, који омогућава управо то: има могућност додавања кеш тагова, контекста и ажурирања max-age.
Да би се поједноставила имплементација овог интерфејса, постоји још једна корисна особина: RefinableCacheableDependencyTrait.
О ентитетима и објектима конфигурације
Сви ентитети у Друпалу 8 (језгро, конриб и прилагођени) имплементирају EntityInterface, који проширује како CacheableDependencyInterface тако и RefinableCacheableDependencyInterface. Поред тога, сви ентитети у језгру Друпала 8 наслеђују апстрактну базичну класу Entity, а препоручује се да то ураде и конриб/прилагођени ентитети. Ово значи да сваки појединачни ентитет са којим интерагујете у Друпалу 8 аутоматски има усклађене кеш тагове (<entity type>:<entity ID>, нпр. node:5 и user:3) и кеш контексте који одражавају превод.
Сви објекти конфигурације у језгру Друпала 8 наслеђују апстрактну базичну класу ConfigBase, која имплементира и CacheableDependencyInterface и RefinableCacheableDependencyInterface. То значи да сваки појединачни објекат конфигурације са којим интерагујете у Друпалу 8 аутоматски има усклађене кеш тагове (у облику config:<configuration name>, нпр. config:system.performance) и кеш контексте који одражавају преклапања конфигурације (превод је једини пример у језгру).
Коначно, сви ентитети и објекти конфигурације у Друпалу 8 аутоматски имају кеш контексте језика садржаја/интерфејса (редом) захваљујући EntityManager::getTranslationFromContext() и LanguageConfigFactoryOverride::getCacheableMetadata($name).
Коришћење објеката који су кеширане зависности
Рендеровање је најчешћи пример зависности од објекта који је кеширана зависност. Да бисмо то поједноставили, имамо RendererInterface::addCacheableDependency($build, $dependency) — где је $build рендер низ који зависи од објекта $dependency; метаподаци кеширане зависности ће се аутоматски „упити“ у рендер низ. Ово значи да ће рендер низ бити неважећи сваки пут када неважећи кеш таг објекта доведе до кеширања друге верзије, ако се користи други превод (тј. кеш контекст језика садржаја се пресликава на други језик), и аутоматски ће истећи ако зависност има max-age који није перманентан.
Погледајте кеширање рендер низова - конкретан пример за комплетан пример.
Други добар пример су провере приступа које враћају AccessResult објекте, који такође имају метод AccessResult::addCacheableDependency($dependency). Обратите пажњу да овде имамо само параметар $dependency, јер можемо чувати метаподаци о кеширању прослеђених зависности у самом AccessResult објекту. (Рендер са својим рендер низовима је изузетак.)