@@ -549,49 +549,39 @@ protected function lock(Request $request, Response $entry)
549
549
// try to acquire a lock to call the backend
550
550
$ lock = $ this ->store ->lock ($ request );
551
551
552
+ if (true === $ lock ) {
553
+ // we have the lock, call the backend
554
+ return false ;
555
+ }
556
+
552
557
// there is already another process calling the backend
553
- if (true !== $ lock ) {
554
- // check if we can serve the stale entry
555
- if (null === $ age = $ entry ->headers ->getCacheControlDirective ('stale-while-revalidate ' )) {
556
- $ age = $ this ->options ['stale_while_revalidate ' ];
557
- }
558
558
559
- if (abs ($ entry ->getTtl ()) < $ age ) {
560
- $ this ->record ($ request , 'stale-while-revalidate ' );
559
+ // May we serve a stale response?
560
+ if ($ this ->mayServeStaleWhileRevalidate ($ entry )) {
561
+ $ this ->record ($ request , 'stale-while-revalidate ' );
561
562
562
- // server the stale response while there is a revalidation
563
- return true ;
564
- }
565
-
566
- // wait for the lock to be released
567
- $ wait = 0 ;
568
- while ($ this ->store ->isLocked ($ request ) && $ wait < 5000000 ) {
569
- usleep (50000 );
570
- $ wait += 50000 ;
571
- }
563
+ return true ;
564
+ }
572
565
573
- if ($ wait < 5000000 ) {
574
- // replace the current entry with the fresh one
575
- $ new = $ this ->lookup ($ request );
576
- $ entry ->headers = $ new ->headers ;
577
- $ entry ->setContent ($ new ->getContent ());
578
- $ entry ->setStatusCode ($ new ->getStatusCode ());
579
- $ entry ->setProtocolVersion ($ new ->getProtocolVersion ());
580
- foreach ($ new ->headers ->getCookies () as $ cookie ) {
581
- $ entry ->headers ->setCookie ($ cookie );
582
- }
583
- } else {
584
- // backend is slow as hell, send a 503 response (to avoid the dog pile effect)
585
- $ entry ->setStatusCode (503 );
586
- $ entry ->setContent ('503 Service Unavailable ' );
587
- $ entry ->headers ->set ('Retry-After ' , 10 );
566
+ // wait for the lock to be released
567
+ if ($ this ->waitForLock ($ request )) {
568
+ // replace the current entry with the fresh one
569
+ $ new = $ this ->lookup ($ request );
570
+ $ entry ->headers = $ new ->headers ;
571
+ $ entry ->setContent ($ new ->getContent ());
572
+ $ entry ->setStatusCode ($ new ->getStatusCode ());
573
+ $ entry ->setProtocolVersion ($ new ->getProtocolVersion ());
574
+ foreach ($ new ->headers ->getCookies () as $ cookie ) {
575
+ $ entry ->headers ->setCookie ($ cookie );
588
576
}
589
-
590
- return true ;
577
+ } else {
578
+ // backend is slow as hell, send a 503 response (to avoid the dog pile effect)
579
+ $ entry ->setStatusCode (503 );
580
+ $ entry ->setContent ('503 Service Unavailable ' );
581
+ $ entry ->headers ->set ('Retry-After ' , 10 );
591
582
}
592
583
593
- // we have the lock, call the backend
594
- return false ;
584
+ return true ;
595
585
}
596
586
597
587
/**
@@ -710,4 +700,41 @@ private function record(Request $request, $event)
710
700
}
711
701
$ this ->traces [$ request ->getMethod ().' ' .$ path ][] = $ event ;
712
702
}
703
+
704
+ /**
705
+ * Checks whether the given (cached) response may be served as "stale" when a revalidation
706
+ * is currently in progress.
707
+ *
708
+ * @param Response $entry
709
+ *
710
+ * @return bool True when the stale response may be served, false otherwise.
711
+ */
712
+ private function mayServeStaleWhileRevalidate (Response $ entry )
713
+ {
714
+ $ timeout = $ entry ->headers ->getCacheControlDirective ('stale-while-revalidate ' );
715
+
716
+ if ($ timeout === null ) {
717
+ $ timeout = $ this ->options ['stale_while_revalidate ' ];
718
+ }
719
+
720
+ return abs ($ entry ->getTtl ()) < $ timeout ;
721
+ }
722
+
723
+ /**
724
+ * Waits for the store to release a locked entry.
725
+ *
726
+ * @param Request $request The request to wait for
727
+ *
728
+ * @return bool True if the lock was released before the internal timeout was hit; false if the wait timeout was exceeded.
729
+ */
730
+ private function waitForLock (Request $ request )
731
+ {
732
+ $ wait = 0 ;
733
+ while ($ this ->store ->isLocked ($ request ) && $ wait < 5000000 ) {
734
+ usleep (50000 );
735
+ $ wait += 50000 ;
736
+ }
737
+
738
+ return $ wait < 5000000 ;
739
+ }
713
740
}
0 commit comments