public function cache($key, callable $cachedCallable, $ttl, callable $onNoStaleCacheCallable = null)
{
$value = $this->getValue($key);
if ($value->hasResult() && !$value->isStale()) {
return $value->getResult();
}
if (!$ttl instanceof Ttl) {
$ttl = new Ttl($ttl);
}
$lock_acquired = $this->lockManager->acquire($key, $ttl->getLockTtl());
if (!$lock_acquired) {
if ($value->hasResult()) {
// serve stale if present
return $value->getResult();
}
if (!$onNoStaleCacheCallable) {
$onNoStaleCacheCallable = $this->onNoStaleCacheCallable;
}
if ($onNoStaleCacheCallable !== null) {
$event = new NoStaleCacheEvent($this, $key, $cachedCallable, $ttl);
call_user_func($onNoStaleCacheCallable, $event);
if ($event->hasResult()) {
return $event->getResult();
}
}
}
$result = call_user_func($cachedCallable);
$this->setResult($key, $result, $ttl);
if ($lock_acquired) {
$this->lockManager->release($key);
}
return $result;
}