@@ -549,49 +549,39 @@ protected function lock(Request $request, Response $entry)
549549// try to acquire a lock to call the backend
550550$ lock =$ this ->store ->lock ($ request );
551551
552+ if (true ===$ lock ) {
553+ // we have the lock, call the backend
554+ return false ;
555+ }
556+
552557// 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- }
558558
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 ' );
561562
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+ }
572565
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 );
588576 }
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 );
591582 }
592583
593- // we have the lock, call the backend
594- return false ;
584+ return true ;
595585 }
596586
597587/**
@@ -710,4 +700,41 @@ private function record(Request $request, $event)
710700 }
711701$ this ->traces [$ request ->getMethod ().' ' .$ path ][] =$ event ;
712702 }
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+ }
713740}