Puncte:2

Se depanează antetul „UNCACHEABLE”.

drapel in

Avem un site în care pagina de pornire nu este stocată în cache și conține anteturile:

x-cache: DOAMNA, DOAMNA
x-cache-hits: 0, 0
x-content-type-options: nosniff
x-drupal-dynamic-cache: UNCACHEABLE

Am restrâns acest lucru la conținutul regiunilor de conținut și am dezactivat „Conținutul paginii principale” pentru prima pagină. Acest lucru mi-a dat apoi un HIT cache și nu a mai răspuns ca UNCACHEABLE.De acolo, l-am restrâns la un formatator de câmp folosit pe un paragraf. Avem unul personalizat care extinde formatatorul de randare a entității normale.

Dacă îl schimb înapoi la formatatorul original „Render entity”, totul este în regulă. Deci, trebuie să fie ceva ce facem în acest formatator personalizat care cauzează problema.

Pot vedea când urmăresc cu xdebug că shouldCacheResponse din DynamicPageCacheSubscriber returnează FALSE, deoarece ceva setează vârsta maximă la 0 (nu prin cod). Se pare că apelurile la addCacheableDependency pot declanșa acest comportament în formatator:

În esență, formatatorul adaugă date cache la randare, astfel încât, dacă oricare dintre elementele sale de referință este actualizat, memoria cache ar trebui să fie invalidată pentru acel paragraful gazdă, astfel încât să redea:

     $view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
      $elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());

      încerca {
        $parent = $items->getParent();
        $parent_entity = $parent->getValue();
        $elements[$delta]['#cache']['keys'][] = $parent_entity->id();
        $elements[$delta]['#cache']['keys'][] = $parent_entity->bundle();
        $elements[$delta]['#cache']['keys'][] = $parent_entity->getEntityTypeId();
        $elements[$delta]['#cache']['keys'][] = 'delta_' . $delta;
        $elements[$delta]['#cache']['keys'][] = 'context_aware';

        $this->renderer->addCacheableDependency($elements[$delta], $parent);

        if ($entity->hasField('câmp_autor')) {
          $copil = $entitate->câmp_autor->entitate;

          dacă (isset($copil)) {
            $this->renderer->addCacheableDependency($elements[$delta], $child);
          }
        }

        // declarații similare cu addCacheableDependency

Dacă comentez această linie inițială:

$this->renderer->addCacheableDependency($elements[$delta], $parent);

Apoi primesc un răspuns stocabil în cache.Acest lucru pare să fie pentru că elementul $parent (chiar dacă este un nod sau un paragraf sau o entitate media) declanșează acest lucru:

  /**
   * Creează un obiect CacheableMetadata dintr-un obiect dependent.
   *
   * @param \Drupal\Core\Cache\CacheableDependencyInterface|$obiect mixt
   * Obiectul ale cărui metadate de stocare în cache urmează să fie preluate. Dacă implementează
   * CacheableDependencyInterface, vor fi utilizate metadatele sale de cacheabilitate,
   * în caz contrar, obiectul transmis trebuie presupus a fi necacheabil, deci
   * vârsta maximă 0 este setată.
   *
   * @return static
   */
  funcția publică statică createFromObject($obiect) {
    if ($obiect instanceof CacheableDependencyInterface) {
      $meta = new static();
      $meta->cacheContexts = $object->getCacheContexts();
      $meta->cacheTags = $object->getCacheTags();
      $meta->cacheMaxAge = $object->getCacheMaxAge();
      returneaza $meta;
    }

    // Obiectele care nu implementează CacheableDependencyInterface trebuie presupuse
    // pentru a fi necacheabil, deci setați vârsta maximă 0.
    $meta = new static();
    $meta->cacheMaxAge = 0;
    returneaza $meta;
  }

Setarea cacheMaxAge la 0 deoarece nu este o instanță a CacheableDependencyInterface.

Dacă setez deja cheile cache, este nevoie de această linie:

$this->renderer->addCacheableDependency($elements[$delta], $parent);

Dacă elimin asta, va exista un efect advers (cum ar fi afișarea de randare care nu se redă din nou atunci când elementele la care se face referire sunt salvate)?

4uk4 avatar
drapel cn
Setarea cheilor cache nu este suficientă, aveți nevoie și de etichetele cache. Deci nu eliminați această linie, verificați doar că obiectul nu este NULL.
sonfd avatar
drapel in
Da, cheile cache nu fac nimic - contextele, etichetele și vârsta maximă sunt ceea ce ați dori să vă asigurați că le transferați.
Kevin avatar
drapel in
$parent nu este nul, dar este primit în createFromObject ca o instanță a EntityAdapter (conținând nodul entității sau paragraful) pe care nu îl pot urmări ca implementând CacheableDependencyInterface
4uk4 avatar
drapel cn
OK, acum văd problema, entitatea cu datele din cache este `$parent_entity`.
Kevin avatar
drapel in
Asta am bănuit, mulțumesc pentru confirmare. Schimbarea acesteia returnează un răspuns stocabil în cache în browser.
Puncte:4
drapel in

Aceasta a fost o scufundare bună pentru depanare. După cum a menționat 4k4, problema este prima addCacheableDependency linia.

În loc să trec entitatea gazdă în sine, am trecut din greșeală obiectul de la care a revenit getParent care este un TypedData exemplu care nu se implementează CacheableDependencyInterface - determinând astfel vârsta maximă să fie setată la 0 și NECACHEBIL rezultatul antetului.

Trecerea entității (întors de la getValue()) a rezolvat problema:

    $parent = $items->getParent();
    $parent_entity = $parent->getValue();
    ...
    $this->renderer->addCacheableDependency($elements[$delta], $parent_entity);

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.