/** * Caches specified closure/method/function for specified time. * * As a third argument - instead of integer - you can pass Ttt object to * define grace tll and lock ttl (both optional). * * @param string * @param callable * @param int|\Metaphore\Ttl * @param callable */ 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; }