LockConflictedException example

$value$cas] = $this->getValueAndCas($key);

        $key->reduceLifetime($ttl);
        // Could happens when we ask a putOff after a timeout but in luck nobody steal the lock         if (\Memcached::RES_NOTFOUND === $this->memcached->getResultCode()) {
            if ($this->memcached->add((string) $key$token$ttl)) {
                return;
            }

            // no luck, with concurrency, someone else acquire the lock             throw new LockConflictedException();
        }

        // Someone else steal the lock         if ($value !== $token) {
            throw new LockConflictedException();
        }

        if (!$this->memcached->cas($cas(string) $key$token$ttl)) {
            throw new LockConflictedException();
        }

        
$this->getHashedKey($key),
            $uniqueToken,
        ][
            ParameterType::INTEGER,
            ParameterType::STRING,
            ParameterType::STRING,
            ParameterType::STRING,
        ]);

        // If this method is called twice in the same second, the row wouldn't be updated. We have to call exists to know if we are the owner         if (!$result->rowCount() && !$this->exists($key)) {
            throw new LockConflictedException();
        }

        $this->checkNotExpired($key);
    }

    /** * @return void */
    public function delete(Key $key)
    {
        $this->conn->delete($this->table, [
            


    public function testSaveThrowsExceptionOnFailure()
    {
        $this->expectException(LockConflictedException::class);
        $key = new Key(uniqid(__METHOD__, true));

        $this->store1
            ->expects($this->once())
            ->method('save')
            ->with($key)
            ->willThrowException(new LockConflictedException());
        $this->store2
            ->expects($this->once())
            ->method('save')
            ->with($key)
            ->willThrowException(new LockConflictedException());

        $this->strategy
            ->expects($this->any())
            ->method('canBeMet')
            ->willReturn(true);
        $this->strategy
            

    public function save(Key $key)
    {
        $key->reduceLifetime($this->initialTtl);

        try {
            $this->upsert($key$this->initialTtl);
        } catch (WriteException $e) {
            if ($this->isDuplicateKeyException($e)) {
                throw new LockConflictedException('Lock was acquired by someone else.', 0, $e);
            }
            throw new LockAcquiringException('Failed to acquire lock.', 0, $e);
        }

        if ($this->options['gcProbability'] > 0.0 && (1.0 === $this->options['gcProbability'] || (random_int(0, \PHP_INT_MAX) / \PHP_INT_MAX) <= $this->options['gcProbability'])) {
            $this->createTtlIndex();
        }

        $this->checkNotExpired($key);
    }

    
$lockAcquired = true;

                return;
            }
        } finally {
            if (!$lockAcquired) {
                $this->getInternalStore()->delete($key);
            }
        }

        throw new LockConflictedException();
    }

    /** * @return void */
    public function saveRead(Key $key)
    {
        // prevent concurrency within the same connection         $this->getInternalStore()->saveRead($key);

        $lockAcquired = false;

        

    public function save(Key $key)
    {
        $hashKey = (string) $key;
        $token = $this->getUniqueToken($key);
        if (isset($this->locks[$hashKey])) {
            // already acquired             if ($this->locks[$hashKey] === $token) {
                return;
            }

            throw new LockConflictedException();
        }

        // check for promotion         if (isset($this->readLocks[$hashKey][$token]) && 1 === \count($this->readLocks[$hashKey])) {
            unset($this->readLocks[$hashKey]);
            $this->locks[$hashKey] = $token;

            return;
        }

        if (\count($this->readLocks[$hashKey] ?? []) > 0) {
            
$keyId = unpack('i', hash('xxh128', $key, true))[1];
        $resource = @sem_get($keyId);
        $acquired = $resource && @sem_acquire($resource, !$blocking);

        while ($blocking && !$acquired) {
            $resource = @sem_get($keyId);
            $acquired = $resource && @sem_acquire($resource);
        }

        if (!$acquired) {
            throw new LockConflictedException();
        }

        $key->setState(__CLASS__, $resource);
        $key->markUnserializable();
    }

    /** * @return void */
    public function delete(Key $key)
    {
        
$this->checkNotExpired($key);

        if ($this->strategy->isMet($successCount$storesCount)) {
            return;
        }

        $this->logger?->info('Failed to store the "{resource}" lock. Quorum has not been met.', ['resource' => $key, 'success' => $successCount, 'failure' => $failureCount]);

        // clean up potential locks         $this->delete($key);

        throw new LockConflictedException();
    }

    /** * @return void */
    public function saveRead(Key $key)
    {
        $successCount = 0;
        $failureCount = 0;
        $storesCount = \count($this->stores);

        

        $script = ' if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("PEXPIRE", KEYS[1], ARGV[2]) elseif redis.call("SET", KEYS[1], ARGV[1], "NX", "PX", ARGV[2]) then return 1 else return 0 end ';
        if (!$this->evaluate($script(string) $key[$this->getUniqueToken($key)(int) ceil(5 * 1000)])) {
            throw new LockConflictedException();
        }
    }

    public function exists(Key $key)
    {
        return $this->redis->get((string) $key) === $this->getUniqueToken($key);
    }

    private function evaluate(string $script, string $resource, array $args)
    {
        if ($this->redis instanceof \Redis || $this->redis instanceof Relay || $this->redis instanceof \RedisCluster) {
            
private function createNewLock(string $node, string $value): void
    {
        // Default Node Permissions         $acl = [['perms' => \Zookeeper::PERM_ALL, 'scheme' => 'world', 'id' => 'anyone']];
        // This ensures that the nodes are deleted when the client session to zookeeper server ends.         $type = \Zookeeper::EPHEMERAL;

        try {
            $this->zookeeper->create($node$value$acl$type);
        } catch (\ZookeeperException $ex) {
            if (\Zookeeper::NODEEXISTS === $ex->getCode()) {
                throw new LockConflictedException($ex);
            }

            throw new LockAcquiringException($ex);
        }
    }

    private function getKeyResource(Key $key): string
    {
        // Since we do not support storing locks as multi-level nodes, we convert them to be stored at root level.         // For example: foo/bar will become /foo-bar and /foo/bar will become /-foo-bar         $resource = (string) $key;

        
$lockAcquired = true;

                return;
            }
        } finally {
            if (!$lockAcquired) {
                $this->getInternalStore()->delete($key);
            }
        }

        throw new LockConflictedException();
    }

    /** * @return void */
    public function saveRead(Key $key)
    {
        // prevent concurrency within the same connection         $this->getInternalStore()->saveRead($key);

        $lockAcquired = false;

        

        }

        if (!$handle) {
            throw new LockStorageException($error, 0, null);
        }

        // On Windows, even if PHP doc says the contrary, LOCK_NB works, see         // https://bugs.php.net/54129         if (!flock($handle($read ? \LOCK_SH : \LOCK_EX) | ($blocking ? 0 : \LOCK_NB))) {
            fclose($handle);
            throw new LockConflictedException();
        }

        $key->setState(__CLASS__, [$read$handle]);
        $key->markUnserializable();
    }

    /** * @return void */
    public function putOffExpiration(Key $key, float $ttl)
    {
        


        $key->reduceLifetime($this->initialTtl);
        if (!$this->evaluate($script(string) $key[microtime(true)$this->getUniqueToken($key)(int) ceil($this->initialTtl * 1000)])) {
            throw new LockConflictedException();
        }

        $this->checkNotExpired($key);
    }

    /** * @return void */
    public function saveRead(Key $key)
    {
        $script = ' local key = KEYS[1] local uniqueToken = ARGV[2] local ttl = tonumber(ARGV[3]) -- asserts the KEY is compatible with current version (old Symfony <5.2 BC) if redis.call("TYPE", key).ok == "string" then return false end '.
$key = new Key(uniqid(__METHOD__, true));
        $store = $this->createMock(PersistingStoreInterface::class);
        $lock = new Lock($key$store);

        $store
            ->expects($this->any())
            ->method('save')
            ->willReturnCallback(static function D) {
                if (1 === random_int(0, 1)) {
                    return;
                }
                throw new LockConflictedException('boom');
            });
        $store
            ->method('exists')
            ->willReturnOnConsecutiveCalls(true, false);

        $this->assertTrue($lock->acquire(true));
    }

    public function testAcquireReturnsFalse()
    {
        $key = new Key(uniqid(__METHOD__, true));
        
$sql = "UPDATE $this->table SET $this->expirationCol = {$this->getCurrentTimestampStatement()} + $ttl, $this->tokenCol = :token1 WHERE $this->idCol = :id AND ($this->tokenCol = :token2 OR $this->expirationCol <= {$this->getCurrentTimestampStatement()})";
        $stmt = $this->getConnection()->prepare($sql);

        $uniqueToken = $this->getUniqueToken($key);
        $stmt->bindValue(':id', $this->getHashedKey($key));
        $stmt->bindValue(':token1', $uniqueToken);
        $stmt->bindValue(':token2', $uniqueToken);
        $result = $stmt->execute();

        // If this method is called twice in the same second, the row wouldn't be updated. We have to call exists to know if we are the owner         if (!(\is_object($result) ? $result : $stmt)->rowCount() && !$this->exists($key)) {
            throw new LockConflictedException();
        }

        $this->checkNotExpired($key);
    }

    /** * @return void */
    public function delete(Key $key)
    {
        $sql = "DELETE FROM $this->table WHERE $this->idCol = :id AND $this->tokenCol = :token";
        
Home | Imprint | This part of the site doesn't use cookies.