- $lock_key = "memcache_$cid:$this->bin";
- $cache->valid = FALSE;
-
- if ($cache) {
- // Items that have expired are invalid.
- if (isset($cache->expire) && ($cache->expire != CacheBackendInterface::CACHE_PERMANENT) && ($cache->expire <= REQUEST_TIME)) {
- // If the memcache_stampede_protection variable is set, allow one
- // process to rebuild the cache entry while serving expired content to
- // the rest.
- if ($this->settings->get('stampede_protection', FALSE)) {
- // The process that acquires the lock will get a cache miss, all
- // others will get a cache hit.
- if (!$this->lock->acquire($lock_key, $this->settings->get('stampede_semaphore', 15))) {
- $cache->valid = TRUE;
- }
- }
- }
- else {
- $cache->valid = TRUE;
- }
- }
- // On cache misses, attempt to avoid stampedes when the
- // memcache_stampede_protection variable is enabled.
- else {
- if ($this->settings->get('stampede_protection', FALSE) && !$this->lock->acquire($lock_key, $this->settings->get('stampede_semaphore', 15))) {
- // Prevent any single request from waiting more than three times due to
- // stampede protection. By default this is a maximum total wait of 15
- // seconds. This accounts for two possibilities - a cache and lock miss
- // more than once for the same item. Or a cache and lock miss for
- // different items during the same request.
- // @todo: it would be better to base this on time waited rather than
- // number of waits, but the lock API does not currently provide this
- // information. Currently the limit will kick in for three waits of 25ms
- // or three waits of 5000ms.
- $this->lockCount++;
- if ($this->lockCount <= $this->settings->get('stampede_wait_limit', 3)) {
- // The memcache_stampede_semaphore variable was used in previous
- // releases of memcache, but the max_wait variable was not, so by
- // default divide the semaphore value by 3 (5 seconds).
- $this->lock->wait($lock_key, $this->settings->get('stampede_wait_time', 5));
- $cache = $this->get($cid);
- }
- }