Locks a Request during the call to the backend.
Request $request A Request instance:
Response $entry A Response instance:
Boolean true if the cache entry can be returned even if it is staled, false otherwise
protected function lock(Request $request, Response $entry) {
// try to acquire a lock to call the backend
$lock = $this->store
->lock($request, $entry);
// there is already another process calling the backend
if (true !== $lock) {
// check if we can serve the stale entry
if (null === ($age = $entry->headers
->getCacheControlDirective('stale-while-revalidate'))) {
$age = $this->options['stale_while_revalidate'];
}
if (abs($entry
->getTtl()) < $age) {
$this
->record($request, 'stale-while-revalidate');
// server the stale response while there is a revalidation
return true;
}
// wait for the lock to be released
$wait = 0;
while (is_file($lock) && $wait < 5000000) {
usleep(50000);
$wait += 50000;
}
if ($wait < 2000000) {
// replace the current entry with the fresh one
$new = $this
->lookup($request);
$entry->headers = $new->headers;
$entry
->setContent($new
->getContent());
$entry
->setStatusCode($new
->getStatusCode());
$entry
->setProtocolVersion($new
->getProtocolVersion());
foreach ($new->headers
->getCookies() as $cookie) {
$entry->headers
->setCookie($cookie);
}
}
else {
// backend is slow as hell, send a 503 response (to avoid the dog pile effect)
$entry
->setStatusCode(503);
$entry
->setContent('503 Service Unavailable');
$entry->headers
->set('Retry-After', 10);
}
return true;
}
// we have the lock, call the backend
return false;
}