KernelEvents :: SOLICITUD no se activa en páginas en caché

13

Estoy tratando de implementar un suscriptor de evento KernelEvents :: REQUEST para realizar alguna acción en la carga de la página.

Necesito que este evento se active independientemente de si la página solicitada existe en el caché de Drupal; parece que KernelEvents :: REQUEST no se activa cuando Drupal sirve algo del caché.

¿Hay algún evento que pueda usar para lograr esto, o debo implementar mis requisitos como alguna forma de middleware?

kiamlaluno
fuente
1
El evento SOLICITAR TIENE que activarse, de lo contrario no habría respuesta. En mi humilde opinión, su ES tiene un peso incorrecto y el servicio http_middleware.page_cache (o el caché de página dinámico) está deteniendo la propagación del evento aún más, por lo tanto, su ES no se activará.
El peso / prioridad de ES se establece en 20
Como escribió 4k4, page_cache para usuarios anónimos es un middleware y ocurre mucho antes del evento REQUEST. Podrías escribir tu propio middleware que viene antes, pero quizás quieras reconsiderar tu appraoch. ¿Qué es exactamente lo que debe suceder tan temprano? Tenga en cuenta que el almacenamiento en caché de páginas anónimas incluso puede ocurrir en otros barnices de otro software externo o incluso en los navegadores. Eche un vistazo a cómo el módulo de estadísticas principales realiza un seguimiento de las visitas a la página: con javascript que hace sonar el servidor cuando un usuario lo ejecuta.
Berdir
@ Berdir Es para proporcionar autenticación HTTP para un sitio, similar al módulo Shield, por lo que creo que esto representa un ejemplo válido de algo que debe manejarse lo antes posible en la solicitud. (Soy consciente de que hay un parche del módulo D8 Shield implementado como middleware, supongo que debido a esta limitación).

Respuestas:

13

El caché dinámico suscribe un evento con prioridad 27. Si desea que su código se ejecute antes de eso, debe usar una prioridad> 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];

Que ejecuta DynamicPageCacheSubscriber :: onRequest ..

4k4
fuente
La prioridad se establece en 20
Creo que el problema que tienes es con el evento de la caché dinámica, edité mi respuesta.
4k4
gracias @ 4k4, pero incluso con la prioridad establecida en 30, todavía se comporta igual (reinstalé el módulo y borré todas las memorias caché después de realizar el cambio). ¿Alguna otra idea?
Hay dos cachés. Ahora que tiene prioridad sobre el caché dinámico, todavía queda el caché de la página. El caché de la página se ejecuta antes que el núcleo principal. Puede desinstalar este módulo y probar si el rendimiento es correcto sin él.
4k4
Puedo confirmar que esto funcionó para mí. Tuve una redirección que solo sucedería una vez, antes de que la página se almacenara en caché. Cuando agregué una prioridad ['checkForRediret', 30];, funcionó como se esperaba.
Cyclonecode
6

Drupal 8 tiene caché de dos niveles, caché de página y caché de página dinámico.

Sí, puede interceptar la memoria caché de página dinámica como mencionó @ 4k4. El problema que está teniendo es más probable que intercepte el caché de la página. La clave está aquí .

Hay algunas soluciones para esto:

  1. Agregue una nueva clase que implemente 'HttpKernelInterface' y registre 'http_middleware' con mayor prioridad que 200 (280 lo hará). Vea la clase 'PageCache' y las implementaciones para referencias.

  2. Cree una nueva clase para alterar el 'PageCache' existente extendiéndose desde 'ServiceProviderBase'. Mira esto para referencias aquí . Luego, cree una nueva clase para extender el 'PageCache'.

Aquí hay referencias de código:

Esta es 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');
  }
}

Esto es 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 esperanza ayuda.

kororo
fuente
Esto fue muy útil gracias, resolví el problema implementando la solución 1.
Remco Hoeneveld