/** * Tries to acquire a key lock, otherwise waits until it's released and repeats. * * @param string $key * @throws LockException * @return bool */ public function acquireLock($key) { if (isset($this->keys[$key])) { return $this->increaseLockTimeout($key); } $start = microtime(TRUE); $lockKey = $this->formatLock($key); $maxAttempts = 10; do { $sleepTime = 5000; do { if ($this->client->setNX($lockKey, $timeout = $this->calculateTimeout())) { $this->keys[$key] = $timeout; return TRUE; } if ($this->acquireTimeout !== FALSE && microtime(TRUE) - $start >= $this->acquireTimeout) { throw LockException::acquireTimeout(); } $lockExpiration = $this->client->get($lockKey); $sleepTime += 2500; } while (empty($lockExpiration) || $lockExpiration >= time() && !usleep($sleepTime)); $oldExpiration = $this->client->getSet($lockKey, $timeout = $this->calculateTimeout()); if ($oldExpiration === $lockExpiration) { $this->keys[$key] = $timeout; return TRUE; } } while (--$maxAttempts > 0); throw LockException::highConcurrency(); }
/** * Tries to acquire a key lock, otherwise waits until it's released and repeats. * * @param string $key * @throws LockException * @return bool */ public function acquireLock($key) { if (isset($this->keys[$key])) { return $this->increaseLockTimeout($key); } $lockKey = $this->formatLock($key); $maxAttempts = 10; do { do { if ($this->client->setNX($lockKey, $timeout = $this->calculateTimeout())) { $this->keys[$key] = $timeout; return TRUE; } $lockExpiration = $this->client->get($lockKey); } while (empty($lockExpiration) || $lockExpiration >= time() && !usleep(10000)); $oldExpiration = $this->client->getSet($lockKey, $timeout = $this->calculateTimeout()); if ($oldExpiration === $lockExpiration) { $this->keys[$key] = $timeout; return TRUE; } } while (--$maxAttempts > 0); throw new LockException("Lock couldn't be acquired. Concurrency is too high."); }