Puncte:0

Memorarea în cache a entităților și câmpurile calculate

drapel ph

Am o entitate personalizată la care am adăugat câteva câmpuri calculate, deci clasele implicate sunt:

  • clasa MyEntity extinde ContentEntityBase
  • clasa ComputedFieldA extinde FieldItemList
  • clasa ComputedFieldB extinde FieldItemList

Problema mea este că vreau ca câmpurile calculate fie să nu fie memorate în cache, fie să fie stocate în cache, dar cu o strategie de invalidare diferită.

Este posibil ceea ce vreau? Sau trebuie doar să invalidez memoria cache pentru întreaga entitate?

Editare: câmpul personalizat în sine este practic un număr de rânduri dintr-un alt tabel al bazei de date.Vreau ca numărul respectiv să fie memorat în cache separat, apoi invalidat dacă sunt inserate rânduri noi.

Ieșirea este consumată prin punctul final jsonapi implicit pentru entitate.

Edit 2: Cred că acest lucru este mai complex decât credeam, așa că voi descrie entitățile mai detaliat:

Entitatea A:

  • Are o relație 1:1 cu nodurile bazate pe UUID
  • Are un număr de entități de Entitate B care sunt legate de nod (calculat)
  • Are un calcul bazat pe acel număr (calculat)

Entitatea B:

  • Are o relație N:1 cu nodurile bazate pe NID

Deci, dacă este creată o nouă Entitate B pentru nodul X, atunci vreau ca cache-ul să fie invalidat pe cele două câmpuri calculate ale Entității A pentru nodul XXXX-XXXX-XXXX-XXXX, astfel încât punctul final jsonapi să arate date calculate la zi.

Dacă pot adăuga o etichetă cache a nodului:X la fiecare instanță a câmpului calculat, mă aștept că va realiza ceea ce vreau.

4uk4 avatar
drapel cn
Editarea seamănă mai mult cu o întrebare nouă. Este și acest alt tabel al bazei de date un tabel de entități? Dacă da, puteți folosi hook-urile CRUD ale acelei entități pentru a invalida această entitate sau puteți adăuga eticheta de entitate a celeilalte entități în câmp pentru a o invalida automat în operațiunile CRUD. Dacă nu, trebuie să implementați ceva similar.
4uk4 avatar
drapel cn
Editare 2: dacă este vorba despre diferite tipuri de conținut, noua etichetă de listă de pachete ar putea fi utilă. Consultați https://www.drupal.org/node/3107058
Lambic avatar
drapel ph
Nu, nu este vorba despre diferite tipuri de conținut. Entitatea A și Entitatea B sunt entități de tabel unice personalizate, dar Entitatea A are un câmp uuid care se referă la un anumit nod, iar Entitatea B are un câmp nid care se referă la același nod.
4uk4 avatar
drapel cn
OK, apoi folosiți eticheta `entity_b_list`.
Lambic avatar
drapel ph
Probabil că ar funcționa, dar nu sunt sigur unde adaug acea etichetă. În definiția entității? Implementarea FieldItemList? Altundeva?
4uk4 avatar
drapel cn
Pentru un modul de câmp universal care are astfel de necesități de stocare în cache, cel mai simplu mod este probabil un normalizator personalizat pentru FieldItemList, care poate returna un obiect CacheableNormalization cu eticheta cache. Vezi comentariul meu sub răspuns. Dacă sunteți în căutarea unei soluții ușoare pentru acest caz specific, puteți utiliza un cârlig `mymodule_entity_a_load()` și puteți adăuga eticheta cache la entitate. Vedeți https://stackoverflow.com/questions/68523829/how-do-i-control-the-cacheability-of-a-node-rendered-through-jsonapi-in-drupal
Lambic avatar
drapel ph
Voi fi reclamat pentru că am folosit o implementare hook în revizuirea codului, dar aceasta pare a fi cea mai simplă soluție, mulțumesc!
4uk4 avatar
drapel cn
Implementarea cârligului este ceea ce am găsit la SO. Dacă funcționează, puteți adăuga eticheta listă și la clasa de entitate, vedeți răspunsul editat.
Puncte:3
drapel cn

Nu contează dacă câmpul este calculat. Memorarea în cache depinde de modul în care este redat câmpul în formatatorul de câmp. Metadatele din memoria cache adăugate la matricea de randare apar și sunt îmbinate cu cele ale celorlalte câmpuri și ale entității.

Câmpurile în mod implicit nu sunt stocate în cache singure, dar puteți modifica acest lucru. Dacă câmpul are nevoie de o strategie de stocare în cache diferită, adăugați chei de cache, iar câmpul randat poate fi partajat între câmpurile din alte instanțe de entitate, redate cu aceleași chei de cache. Dacă câmpul este foarte dinamic, adăugați un generator leneș și asigurați-vă că acesta este introdus substituent, fie automat, fie setând #create_placeholder.

Editarea 2:

Clasa de entitate ar putea adăuga o etichetă de listă cache pentru entitatea b:

clasa MyEntity extinde ContentEntityBase {

  /**
   * {@inheritdoc}
   */
  funcția publică getCacheTags() {
    $cache_tags = parent::getCacheTags();
    $cache_tags[] = 'entity_b_list';
    returnează $cache_tags;
  }
Lambic avatar
drapel ph
Deci, se pare că trebuie să-mi definesc propriile formatoare de câmpuri pentru câmpurile pe care vreau să le păstrez în cache? Contează că consum rezultatul final prin jsonapi?
4uk4 avatar
drapel cn
Apoi definiți un FieldNormalizer cu `protected $supportedInterfaceOrClass = ComputedFieldA::class;`

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.