KernelEvents :: REQUEST ไม่ทำงานในหน้าแคช


13

ฉันพยายามที่จะใช้สมาชิก KernelEvents :: REQUEST เพื่อดำเนินการบางอย่างกับการโหลดหน้า

ฉันต้องการให้กิจกรรมนี้เริ่มทำงานโดยไม่คำนึงว่าหน้าเว็บที่ร้องขอนั้นมีอยู่ในแคช Drupal หรือไม่ดูเหมือนว่า KernelEvents :: REQUEST จะไม่ทำงานเมื่อ Drupal ให้บริการบางอย่างจากแคช

มีเหตุการณ์ที่ฉันสามารถใช้เพื่อให้บรรลุสิ่งนี้หรือฉันต้องปฏิบัติตามข้อกำหนดของฉันในฐานะมิดเดิลแวร์บางรูปแบบหรือไม่?


1
เหตุการณ์คำขอได้รับการทริกเกอร์มิฉะนั้นจะไม่มีการตอบสนอง IMHO ES ของคุณมีน้ำหนักไม่ดีและบริการ http_middleware.page_cache (หรือแคชของหน้าแบบไดนามิก) กำลังหยุดการเผยแพร่กิจกรรมต่อไปดังนั้น ES ของคุณจะไม่ถูกเรียกใช้

ES น้ำหนัก / ลำดับความสำคัญถูกตั้งไว้ที่ 20

ตามที่เขียนไว้ 4k4, page_cache สำหรับผู้ใช้ที่ไม่ระบุตัวตนเป็นมิดเดิลแวร์และเกิดขึ้นนานก่อนเหตุการณ์คำขอ คุณสามารถเขียนมิดเดิลแวร์ของคุณเองที่มาก่อนหน้านี้ แต่คุณอาจต้องการพิจารณาการประเมินของคุณใหม่ สิ่งที่ต้องการให้เกิดขึ้นตั้งแต่แรก โปรดทราบว่าการแคชหน้าเว็บโดยไม่ระบุชื่ออาจเกิดขึ้นได้ในซอฟต์แวร์ภายนอกอื่น ๆ หรือแม้แต่เบราว์เซอร์เอง ดูที่โมดูลสถิติหลักติดตามการเข้าชมหน้า: ด้วย javascript ที่ส่ง Ping เซิร์ฟเวอร์เมื่อผู้ใช้ดำเนินการ
Berdir

@Berdir ให้การรับรองความถูกต้องของ http สำหรับไซต์คล้ายกับโมดูล Shield - ดังนั้นฉันคิดว่านี่เป็นตัวอย่างที่ถูกต้องของสิ่งที่ต้องจัดการให้เร็วที่สุดเท่าที่จะทำได้ในคำขอ (ฉันรู้ว่ามี D8 Shield โมดูลปะนำมาใช้เป็นมิดเดิลแวร์ - ฉันถือว่าเนื่องจากข้อ จำกัด นี้)

คำตอบ:


14

แคชแบบไดนามิกสมัครรับกิจกรรมที่มีลำดับความสำคัญ 27 หากคุณต้องการให้โค้ดของคุณทำงานก่อนหน้านั้นคุณต้องใช้ลำดับความสำคัญ> 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];

ซึ่งรันDynamicPageCacheSubscriber :: onRequest ..


ลำดับความสำคัญถูกตั้งไว้ที่ 20

ฉันคิดว่าปัญหาที่คุณมีกับเหตุการณ์จากแคชแบบไดนามิกฉันแก้ไขคำตอบของฉัน
4k4

ขอบคุณ @ 4k4 แต่ถึงแม้จะมีการตั้งค่าลำดับความสำคัญเป็น 30 ก็ยังคงทำงานเหมือนเดิม (ฉันติดตั้งโมดูลและล้างแคชทั้งหมดหลังจากทำการเปลี่ยนแปลง) ความคิดอื่น ๆ ?

มีแคชสองแห่ง ตอนนี้คุณมีความสำคัญมากกว่าแคชแบบไดนามิกยังคงมีแคชหน้า แคชหน้าจะถูกดำเนินการก่อนเคอร์เนลหลัก คุณสามารถถอนการติดตั้งโมดูลนี้และทดสอบว่าประสิทธิภาพดีหรือไม่ถ้าไม่มี
4k4

ฉันสามารถยืนยันได้ว่าสิ่งนี้ได้ผลสำหรับฉัน ฉันมีการเปลี่ยนเส้นทางที่จะเกิดขึ้นเพียงครั้งเดียว - ก่อนหน้านี้จะถูกแคช เมื่อฉันเพิ่มลำดับความสำคัญ['checkForRediret', 30];แล้วมันทำงานตามที่คาดไว้
Cyclonecode

6

Drupal 8 มีแคชสองระดับแคชหน้าและแคชหน้าแบบไดนามิก

ใช่คุณสามารถดักจับแคชหน้าแบบไดนามิกตามที่ @ 4k4 พูดถึง ปัญหาที่คุณพบมีแนวโน้มที่จะดักหน้าแคช ที่สำคัญคือในที่นี่

มีวิธีแก้ไขปัญหาบางประการสำหรับสิ่งนี้:

  1. เพิ่มคลาสใหม่ซึ่งใช้ 'HttpKernelInterface' และลงทะเบียน 'http_middleware' ที่มีลำดับความสำคัญสูงกว่า 200 (280 จะทำได้) ดูคลาส 'PageCache' และการนำไปใช้งานสำหรับการอ้างอิง

  2. สร้างคลาสใหม่เพื่อแก้ไข 'PageCache' ที่มีอยู่โดยขยายจาก 'ServiceProviderBase' ตรวจสอบนี้อ้างอิงที่นี่ จากนั้นสร้างคลาสใหม่เพื่อขยาย 'PageCache'

นี่คือการอ้างอิงรหัส:

นี่คือ 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');
  }
}

นี่คือ 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;
  }
}

หวังว่าจะช่วย


นี่เป็นประโยชน์อย่างมากขอบคุณคุณฉันแก้ไขปัญหาโดยใช้วิธีแก้ไขปัญหาที่ 1
Remco Hoeneveld
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.