KernelEvents :: REQUEST non viene generato nelle pagine memorizzate nella cache


13

Sto cercando di implementare un abbonato di eventi KernelEvents :: REQUEST per eseguire alcune azioni sul caricamento della pagina.

Ho bisogno che questo evento si attivi indipendentemente dal fatto che la pagina richiesta esista nella cache di Drupal - sembra che KernelEvents :: REQUEST non si attivi quando Drupal serve qualcosa dalla cache.

Esiste un evento che posso utilizzare per raggiungere questo obiettivo o devo implementare i miei requisiti come una forma di middleware?


1
L'evento REQUEST DEVE essere attivato, altrimenti non ci sarebbe risposta. IMHO il tuo ES ha un peso scarso e il servizio http_middleware.page_cache (o la cache della pagina dinamica) interrompe ulteriormente la propagazione dell'evento, quindi il tuo ES non verrà attivato.

Il peso / priorità ES è impostato su 20

Come ha scritto 4k4, page_cache per utenti anonimi è un middleware e si verifica molto prima dell'evento RICHIESTA. Potresti scrivere il tuo middleware che viene prima, ma potresti voler riconsiderare la tua valutazione. Cosa deve accadere esattamente così presto? Tieni presente che la memorizzazione nella cache delle pagine anonime potrebbe persino accadere nella vernice di altri software esterni o nei browser stessi. Dai un'occhiata a come il modulo statistico di base tiene traccia delle visite alla pagina: con javascript che esegue il ping del server quando viene eseguito da un utente.
Berdir,

@Berdir Fornisce l'autenticazione http per un sito, simile al modulo Shield - quindi penso che questo rappresenti un valido esempio di qualcosa che deve essere gestito il prima possibile nella richiesta. (Sono consapevole che esiste una patch del modulo D8 Shield implementata come middleware - suppongo a causa di questa limitazione).

Risposte:


14

La cache dinamica sottoscrive un evento con priorità 27. Se si desidera che il codice venga eseguito prima, è necessario utilizzare una priorità> 27:

  public static function getSubscribedEvents() {
    $events = [];

    // Run after AuthenticationSubscriber (necessary for the 'user' cache
    // context; priority 300) and MaintenanceModeSubscriber (Dynamic Page Cache
    // should not be polluted by maintenance mode-specific behavior; priority
    // 30), but before ContentControllerSubscriber (updates _controller, but
    // that is a no-op when Dynamic Page Cache runs; priority 25).
    $events[KernelEvents::REQUEST][] = ['onRequest', 27];

Che esegue DynamicPageCacheSubscriber :: onRequest ..


La priorità è impostata su 20

Penso che il problema che hai sia con l'evento dalla cache dinamica, ho modificato la mia risposta.
4k4,

grazie @ 4k4, ma anche con priorità impostata su 30 si comporta sempre allo stesso modo (ho reinstallato il modulo e ho cancellato tutte le cache dopo aver apportato le modifiche). Altre idee?

Ci sono due cache. Ora che hai la priorità sulla cache dinamica, c'è ancora la cache della pagina. La cache della pagina viene eseguita prima del kernel principale. È possibile disinstallare questo modulo e verificare se le prestazioni sono OK senza di esso.
4k4,

Posso confermare che questo ha funzionato per me. Ho avuto un reindirizzamento che sarebbe successo solo una volta, prima che la pagina fosse memorizzata nella cache. Quando ho aggiunto una priorità, ['checkForRediret', 30];ha funzionato come previsto.
ciclico

6

Drupal 8 ha cache a due livelli, cache di pagina e cache di pagina dinamica.

Sì, puoi intercettare la cache dinamica della pagina come menzionato da @ 4k4. È più probabile che il problema riscontrato intercetti la cache della pagina. La chiave è qui .

Ci sono alcune soluzioni per questo:

  1. Aggiungi una nuova classe che implementa 'HttpKernelInterface' e registra 'http_middleware' con priorità superiore a 200 (280 lo faranno). Vedere la classe "PageCache" e le implementazioni per i riferimenti.

  2. Crea una nuova classe per modificare il "PageCache" esistente estendendolo da "ServiceProviderBase". Dai un'occhiata qui per i riferimenti qui . Quindi, crea una nuova classe per estendere il "PageCache".

Ecco i riferimenti al codice:

Questo è StaticCacheServiceProvider.php:

/**
 * Modifies the language manager service.
 */
class StaticCacheServiceProvider extends ServiceProviderBase
{
  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container)
  {
    // Overrides language_manager class to test domain language negotiation.
    $definition = $container->getDefinition('http_middleware.page_cache');
    $definition->setClass('Drupal\your_module\StackMiddleware\StaticCache');
  }
}

Questo è StaticCache.php:

/**
 * Executes the page caching before the main kernel takes over the request.
 */
class StaticCache extends PageCache
{
  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  {
    // do special logic here.

    $response = parent::handle($request, $type, $catch);

    return $response;
  }
}

La speranza aiuta.


Questo è stato molto utile grazie, ho risolto il problema implementando la soluzione 1.
Remco Hoeneveld,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.