KernelEvents :: REQUEST nie jest uruchamiany na buforowanych stronach

13

Usiłuję zaimplementować subskrybenta zdarzenia KernelEvents :: REQUEST, aby wykonać pewne działanie podczas ładowania strony.

Potrzebuję tego zdarzenia do uruchomienia niezależnie od tego, czy żądana strona istnieje w pamięci podręcznej Drupal - wygląda na to, że KernelEvents :: REQUEST nie uruchamia się, gdy Drupal podaje coś z pamięci podręcznej.

Czy istnieje zdarzenie, którego mogę użyć, aby to osiągnąć, czy też muszę wdrożyć moje wymagania jako formę oprogramowania pośredniego?

kiamlaluno
źródło
1
Zdarzenie ZAPYTAJ MUSI zostać uruchomione, w przeciwnym razie nie byłoby odpowiedzi. IMHO twoja ES ma złą wagę, a usługa http_middleware.page_cache (lub dynamiczna pamięć podręczna strony) jeszcze bardziej zatrzymuje propagację zdarzenia, dlatego twoja ES nie zostanie uruchomiona.
Waga / priorytet ES jest ustawiona na 20
Jak napisał 4k4, page_cache dla anonimowych użytkowników jest oprogramowaniem pośrednim i dzieje się na długo przed zdarzeniem REQUEST. Możesz napisać własne oprogramowanie pośrednie, które pojawi się wcześniej, ale możesz ponownie rozważyć swoją ocenę. Co dokładnie musi się wydarzyć tak wcześnie? Należy pamiętać, że anonimowe buforowanie stron może się nawet zdarzyć w przypadku innego oprogramowania zewnętrznego lub nawet samych przeglądarek. Zobacz, jak moduł statystyk podstawowych śledzi odwiedziny na stronie: za pomocą javascript, który pinguje serwer, gdy użytkownik go wykonuje.
Berdir
@Berdir Zapewnia uwierzytelnianie HTTP dla witryny, podobnie jak moduł Shield - więc myślę, że stanowi to prawidłowy przykład czegoś, z czym należy się zająć jak najwcześniej w żądaniu. (Wiem, że łatka modułu D8 Shield została zaimplementowana jako oprogramowanie pośrednie - przypuszczam, że z powodu tego ograniczenia).

Odpowiedzi:

14

Dynamiczna pamięć podręczna subskrybuje zdarzenie o priorytecie 27. Jeśli chcesz, aby Twój kod działał wcześniej, musisz użyć priorytetu> 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];

Który uruchamia DynamicPageCacheSubscriber :: onRequest ..

4k4
źródło
Priorytet jest ustawiony na 20
Myślę, że masz problem ze zdarzeniem z dynamicznej pamięci podręcznej, zredagowałem swoją odpowiedź.
4k4
dzięki @ 4k4, ale nawet z priorytetem ustawionym na 30, nadal zachowuje się tak samo (ponownie zainstalowałem moduł i wyczyściłem wszystkie pamięci podręczne po wprowadzeniu zmian). Jakieś inne pomysły?
Istnieją dwie skrzynki. Teraz, gdy masz priorytet nad dynamiczną pamięcią podręczną, nadal istnieje pamięć podręczna strony. Pamięć podręczna strony jest wykonywana przed głównym jądrem. Możesz odinstalować ten moduł i sprawdzić, czy wydajność jest w porządku bez niego.
4k4
Mogę potwierdzić, że to zadziałało dla mnie. Miałem przekierowanie, które zdarzy się tylko raz - zanim strona zostanie buforowana. Kiedy dodałem priorytet ['checkForRediret', 30];, działało to zgodnie z oczekiwaniami.
Kod cyklonowy
6

Drupal 8 ma dwupoziomową pamięć podręczną, pamięć podręczną strony i dynamiczną pamięć podręczną strony.

Tak, możesz przechwycić dynamiczną pamięć podręczną strony, jak wspomniano w @ 4k4. Wystąpił problem, który prawdopodobnie przechwytuje pamięć podręczną strony. Klucz jest tutaj .

Istnieje na to kilka rozwiązań:

  1. Dodaj nową klasę, która implementuje „HttpKernelInterface” i zarejestruj „http_middleware” o wyższym priorytecie niż 200 (280 zrobi). Zobacz klasę i implementacje „PageCache” dla odniesień.

  2. Utwórz nową klasę, aby zmienić istniejący „PageCache”, rozszerzając z „ServiceProviderBase”. Sprawdź to, aby uzyskać odniesienia tutaj . Następnie utwórz nową klasę, aby rozszerzyć „PageCache”.

Oto odniesienia do kodu:

To jest 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');
  }
}

To jest 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;
  }
}

Nadzieja pomaga.

kororo
źródło
Było to bardzo pomocne, dziękuję, rozwiązałem problem, wdrażając rozwiązanie 1.
Remco Hoeneveld,