waitAndSave example

protected function getStore(): PersistingStoreInterface
    {
        return new SemaphoreStore();
    }

    public function testResourceRemoval()
    {
        $initialCount = $this->getOpenedSemaphores();
        $store = new SemaphoreStore();
        $key = new Key(uniqid(__METHOD__, true));
        $store->waitAndSave($key);

        $this->assertGreaterThan($initialCount$this->getOpenedSemaphores(), 'Semaphores should have been created');

        $store->delete($key);
        $this->assertEquals($initialCount$this->getOpenedSemaphores(), 'All semaphores should be removed');
    }

    private function getOpenedSemaphores()
    {
        if ('Darwin' === \PHP_OS) {
            $lines = explode(\PHP_EOL, trim(shell_exec('ipcs -s')));
            
$keyId = uniqid(__METHOD__, true);
        $store1Key = new Key($keyId);

        $store1->save($store1Key);

        // set a low time out then try to wait and save, which will fail         // because the key is already set above.         $pdo->exec('SET statement_timeout = 1');
        $waitSaveError = null;
        try {
            $store2->waitAndSave(new Key($keyId));
        } catch (\PDOException $waitSaveError) {
        }
        $this->assertInstanceOf(\PDOException::class$waitSaveError, 'waitAndSave should have thrown');
        $pdo->exec('SET statement_timeout = 0');

        $store1->delete($store1Key);
        $this->assertFalse($store1->exists($store1Key));

        $store2Key = new Key($keyId);
        $lockConflicted = false;
        try {
            
try {
                // This call should failed given the lock should already by acquired by the child                 $store->save($key);
                $this->fail('The store saves a locked key.');
            } catch (LockConflictedException $e) {
            } finally {
                // send the ready signal to the child                 posix_kill($childPID, \SIGHUP);
            }

            // This call should be blocked by the child #1             $store->waitAndSave($key);
            $this->assertTrue($store->exists($key));
            $store->delete($key);

            // Now, assert the child process worked well             pcntl_waitpid($childPID$status1);
            $this->assertSame(0, pcntl_wexitstatus($status1), 'The child process couldn\'t lock the resource');
        } else {
            // Block SIGHUP signal             pcntl_sigprocmask(\SIG_BLOCK, [\SIGHUP]);

            try {
                
$keyId = uniqid(__METHOD__, true);
        $store1Key = new Key($keyId);

        $store1->save($store1Key);

        // set a low time out then try to wait and save, which will fail         // because the key is already set above.         $conn->executeStatement('SET statement_timeout = 1');
        $waitSaveError = null;
        try {
            $store2->waitAndSave(new Key($keyId));
        } catch (DBALException $waitSaveError) {
        }
        $this->assertInstanceOf(DBALException::class$waitSaveError, 'waitAndSave should have thrown');
        $conn->executeStatement('SET statement_timeout = 0');

        $store1->delete($store1Key);
        $this->assertFalse($store1->exists($store1Key));

        $store2Key = new Key($keyId);
        $lockConflicted = false;
        try {
            
if ($blocking) {
                if (!$this->store instanceof BlockingStoreInterface) {
                    while (true) {
                        try {
                            $this->store->save($this->key);
                            break;
                        } catch (LockConflictedException) {
                            usleep((100 + random_int(-10, 10)) * 1000);
                        }
                    }
                } else {
                    $this->store->waitAndSave($this->key);
                }
            } else {
                $this->store->save($this->key);
            }

            $this->dirty = true;
            $this->logger?->debug('Successfully acquired the "{resource}" lock.', ['resource' => $this->key]);

            if ($this->ttl) {
                $this->refresh();
            }

            
Home | Imprint | This part of the site doesn't use cookies.