KernelEvents :: REQUEST, önbelleğe alınmış sayfalarda tetiklenmez


13

Sayfa yükü üzerinde bazı eylemler gerçekleştirmek için bir KernelEvents :: REQUEST olay abone uygulamaya çalışıyorum.

İstenilen sayfa Drupal önbellekte olup olmadığına bakılmaksızın bu olayı ateşlemem gerekiyor - Drupal önbellekten bir şey sunduğunda KernelEvents :: REQUEST tetiklenmiyor gibi görünüyor.

Bunu başarmak için kullanabileceğim bir olay var mı veya gereksinimlerimi bir çeşit ara katman yazılımı olarak mı uygulamalıyım?


1
REQUEST olayının tetiklenmesi gerekir, aksi takdirde yanıt verilmez. İmho sizin ES kötü ağırlığa sahiptir dolayısıyla sizin ES tetiklenen almazsınız, ileri ve olayın http_middleware.page_cache (veya dinamik sayfa önbellek) hizmeti durduruluyor yayılmasını.

ES ağırlığı / önceliği 20 olarak ayarlandı

4k4'ün yazdığı gibi, anonim kullanıcılar için page_cache bir ara katman yazılımıdır ve REQUEST olayından çok önce gerçekleşir. Daha önce gelen kendi ara katman yazılımınızı yazabilirsiniz, ancak değerlendirmenizi yeniden gözden geçirmek isteyebilirsiniz. Bu kadar erken ne olmalı? Anonim sayfa önbelleğe almanın, diğer harici yazılımları veya hatta tarayıcıların verniklemesinde bile olabileceğini unutmayın. Çekirdek istatistik modülünün sayfa ziyaretlerini nasıl izlediğine bir göz atın: Bir kullanıcı yürüttüğünde sunucuya ping yapan javascript ile.
Berdir

@Berdir Bu, Shield modülüne benzer bir site için http kimlik doğrulaması sağlamaktır - bu nedenle, istekte mümkün olduğunca erken ele alınması gereken bir şeyin geçerli bir örneğini temsil ettiğini düşünüyorum. (D8 Shield modül yamasının ara katman yazılımı olarak uygulandığının farkındayım - bu sınırlama nedeniyle varsayıyorum).

Yanıtlar:


14

Dinamik önbellek 27 önceliğine sahip bir etkinliğe abone olur. Kodunuzun bundan önce çalışmasını istiyorsanız,> 27 önceliğini kullanmanız gerekir:

  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];

Hangi DynamicPageCacheSubscriber :: onRequest çalıştıran ..


Öncelik 20 olarak ayarlanmıştır

Bence sorun dinamik önbellekten olay ile ilgili, cevabımı düzenledim.
4k4

@ 4k4 teşekkürler, ancak öncelik 30'a ayarlanmış olsa bile yine de aynı davranır (modülü yeniden yükledim ve değişiklik yaptıktan sonra tüm önbellekleri temizledim). Başka fikir var mı?

İki önbellek var. Artık dinamik önbelleğe göre önceliğiniz olduğuna göre hala sayfa önbelleği var. Sayfa önbelleği ana çekirdekten önce yürütülür. Bu modülü kaldırabilir ve performansın onsuz iyi olup olmadığını test edebilirsiniz.
4k4

Bunun benim için işe yaradığını doğrulayabilirim. Sayfa önbelleğe alınmadan önce yalnızca bir kez gerçekleşecek bir yönlendirme yaptım. Bir öncelik eklediğimde ['checkForRediret', 30];beklendiği gibi çalıştı.
Cyclonecode

6

Drupal 8'de iki düzey önbellek, sayfa önbelleği ve dinamik sayfa önbelleği bulunur.

Evet, dinamik sayfa önbelleğini @ 4k4'ten bahsettiğimiz gibi engelleyebilirsiniz. Karşılaştığınız sorunun sayfa önbelleğini durdurma olasılığı daha yüksektir. Anahtar burada .

Bunun için birkaç çözüm var:

  1. 'HttpKernelInterface' uygulayan yeni bir sınıf ekleyin ve 'http_middleware' i 200'den yüksek önceliğe kaydedin (280 yapacaktır). Referanslar için bkz. 'PageCache' sınıfı ve uygulamaları.

  2. 'ServiceProviderBase' öğesinden genişleterek varolan 'PageCache'i değiştirmek için yeni bir sınıf oluşturun. Buradaki referanslar için buna göz atın . Ardından, 'PageCache'i genişletmek için yeni bir sınıf oluşturun.

Kod referansları:

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

Bu 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;
  }
}

Umut yardımcı olur.


Bu çok yararlı oldu, çözüm 1'i uygulayarak sorunu
çözdüm
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.