CacheableDependencyInterface
Կեշի մետատվյալների (կեշի թեգեր, կեշի կոնտեքստներ և max-age) հետ աշխատությունը հեշտացնելու համար Drupal 8-ում կա CacheableDependencyInterface:
Ինչո՞ւ?
Դիտարկեք իրավիճակը, երբ դուք պետք է ձեռքով ստեղծեք կեշի թեգերը յուրաքանչյուր առանձին օբյեկտի և կոնֆիգուրացիոն օբյեկտի համար, որոնք օգտագործվում են ռենդերային զանգվածում (կամ այլ հաշվարկներում), և բազմալեզու կայքում նաև ձեռքով ավելացնեք անհրաժեշտ կեշի կոնտեքստները (թարգմանված օբյեկտների կամ կոնֆիգուրացիայի լեզվի վերաշնորհման համար):
Եվ ոչ միայն սուբյեկտները և կոնֆիգուրացիան, այլ նաև մուտքի արդյունքները, բլոկների պլագինները, մենյուի հղումները, կոնտեքստային պլագինները, պայմանների պլագինները և այլն, քանի որ դրանք բոլորը վերջանում են ռենդերինգով (հատուկ տեսակ հաշվարկների), որոնք մենք ցանկանում ենք կեշավորել:
Drupal 8-ի սկզբնական օրերին սա տեղի էր ունենում ձեռքով, ինչը անապահով էր և սխալների մեծ հնարավորություն ուներ:
Դրա պատճառով ստեղծվեց CacheableDependencyInterface-ը, որը, ինչպես անունն է ցույց տալիս, հնարավորություն է տալիս օբյեկտներին, որոնք իրականացնում են այս ինտերֆեյսը, ավտոմատ դառնալ կեշավորվող կախվածություններ:
Օրինակ, երբ ստեղծում եք ռենդերային զանգված՝ <p>Hi, %user, welcome to %site!</p>
, դուք կախված եք ինչպես User օբյեկտից, այնպես էլ system.site կոնֆիգուրացիոն օբյեկտից։ Երբ այս ռենդերային զանգվածը կեշավորվում է, այն պահպանում է և՛ օգտվողի օբյեկտը, և՛ կոնֆիգուրացիայի օբյեկտը որպես կեշավորվող կախվածություններ:
CacheableDependencyInterface-ը կարող է իրականացվել ցանկացած արժեքային օբյեկտի կողմից (դա տվյալների տրամաբանական միավոր ներկայացնող օբյեկտ է): Եթե նայեք նրա API փաստաթղթին, կտեսնեք, որ այն իրականացված է Drupal 8-ի շատ կարևոր օբյեկտների կողմից։ Իրականում կարելի է ասել, որ այն իրականացվում է գրեթե բոլոր օբյեկտների կողմից, որոնց հետ դուք աշխատում եք Drupal 8-ում կոդ գրելիս:
Կա երկու ծայրահեղ դեպք, որոնք հաճախ հանդիպում են, որոնց համար Drupal-ը ունի հարմար հատկություններ՝ անփոփոխ օբյեկտի դեպքը, որը հետևաբար կեշավորվում է հավերժ (UnchangingCacheableDependencyTrait, որը միշտ վերադարձնում է max-age === permanent), և այն դեպքը, երբ օբյեկտը միշտ դինամիկ է և հետևաբար երբեք չի կեշավորվում (UncacheableDependencyTrait, որը միշտ վերադարձնում է max-age === 0):
RefinableCacheableDependencyInterface
Բայց CacheableDependencyInterface-ը կարող է աշխատել միայն օբյեկտի «ձեզ բնորոշ», «կանոնավոր» կեշավորման մետատվյալների հետ: Դրան մոտենալու մի քանի տարբերակներ կան:
Լավագույն օրինակներն են սուբյեկտների թարգմանությունները (մեկ և նույն սուբյեկտը նույն սուբյեկտի նույնանուն տարբեր թարգմանությամբ) և կոնֆիգուրացիայի թարգմանությունները (մեկ և նույն կոնֆիգուրացիոն օբյեկտը նույն անունով, բայց լեզվային վերաշնորհմամբ):
Այս բոլոր դեպքերում արդեն առկա կեշավորման մետատվյալները (օրինակ՝ node:5 կեշի թեգեր) համարվում են կիրառելի, բայց օրինակ սուբյեկտի դեպքում պետք է ավելացնել կեշի լեզվի կոնտեքստ ('languages:'. LanguageInterface::TYPE_CONTENT)՝ ցույց տալու համար, որ սուբյեկտը կախված է ընտրված լեզվից: Նույն կերպ կոնֆիգուրացիայի օբյեկտի դեպքում պետք է կիրառվի ինտերֆեյսի լեզվի կեշի կոնտեքստ ('languages:'. LanguageInterface::TYPE_INTERFACE):
Օրինակ՝ հնարավոր է, որ «Pirate Day» մոդուլը ունենա կոնֆիգուրացիայի վերաշնորհում, որը գործում է միայն «Pirate Day»-ին՝ ավելացնելով «yar», «har» և պատահական թութակներ։ Այդ դեպքում կոնֆիգուրացիոն օբյեկտները կունենան «pirate_day» կեշի կոնտեքստը:
Այս ամենի համար ստեղծվեց RefinableCacheableDependencyInterface, որն ունի հնարավորություններ ավելացնել կեշի թեգեր, կոնտեքստներ և թարմացնել max-age-ը:
Այս ինտերֆեյսի հեշտացման համար կա նաև RefinableCacheableDependencyTrait:
Սուբյեկտներ և կոնֆիգուրացիոն օբյեկտներ
Բոլոր սուբյեկտները Drupal 8-ում (core, contrib և custom) իրականացնում են EntityInterface-ը, որը ընդլայնում է և՛ CacheableDependencyInterface-ը, և՛ RefinableCacheableDependencyInterface-ը։ Բացի այդ, բոլոր սուբյեկտները core-ում ընդլայնում են Entity աբստրակտ բազային դասը, իսկ contrib/custom մոդուլներին խորհուրդ է տրվում նույնը անել։ Այսինքն՝ յուրաքանչյուր սուբյեկտ Drupal 8-ում ավտոմատ կերպով ունի համապատասխան կեշի թեգեր (օրինակ՝ node:5, user:3) և կեշի կոնտեքստներ թարգմանության համար։
Բոլոր կոնֆիգուրացիոն օբյեկտները core-ում ընդլայնում են ConfigBase աբստրակտ բազային դասը, որը իրականացնում է և՛ CacheableDependencyInterface, և՛ RefinableCacheableDependencyInterface։ Այսինքն՝ յուրաքանչյուր կոնֆիգուրացիոն օբյեկտ Drupal 8-ում ունի համապատասխան կեշի թեգեր (օրինակ՝ config:system.performance) և կեշի կոնտեքստներ, որոնք արտացոլում են կոնֆիգուրացիայի վերաշնորհումները (օրինակ՝ թարգմանությունները)։
Վերջապես, բոլոր սուբյեկտներն ու կոնֆիգուրացիոն օբյեկտները Drupal 8-ում ավտոմատ ունեն բովանդակության կամ ինտերֆեյսի լեզվի կեշի կոնտեքստներ համապատասխանաբար՝ շնորհիվ EntityManager::getTranslationFromContext() և LanguageConfigFactoryOverride::getCacheableMetadata()։
Կեշավորվող կախվածություններ ունեցող օբյեկտների օգտագործումը
Ռենդերինգը կեշավորվող կախվածությունների ամենատարածված օրինակն է: Դրա հեշտացման համար ունենք RendererInterface::addCacheableDependency($build, $dependency), որտեղ $build-ը ռենդերային զանգվածն է, որը կախված է $dependency օբյեկտից։ Կեշավորվող օբյեկտի մետատվյալները ավտոմատապես ներծծվում են ռենդերային զանգվածում։ Սա նշանակում է, որ ռենդերային զանգվածը կդադարի գործող լինել, երբ կեշի թեգերից որևէ մեկը դադարի գործող լինել՝ ապահովելով տարբեր լեզուների կամ max-age փոփոխվող կախվածության ավտոմատ թարմացում։
Ստուգեք ռենդերային զանգվածների կեշավորման կոնկրետ օրինակ
Բազմիցս լավ օրինակը մուտքի ստուգումներ են, որոնք վերադարձնում են AccessResult օբյեկտներ՝ ունենալով addCacheableDependency() մեթոդ։ Ուշադրություն դարձրեք, որ այստեղ ունենք միայն $dependency պարամետր, քանի որ կեշավորման մետատվյալները պահվում են հենց մուտքի արդյունքի օբյեկտի վրա։ (Ռենդերինգը բացառություն է, քանի որ այն օգտագործում է ռենդերային զանգվածներ):