From 37ec8695114c0094f863969944dbe13489893a81 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 30 Apr 2017 08:55:30 -0700 Subject: [PATCH] [Lock] remove the component from 3.3 --- composer.json | 1 - src/Symfony/Component/Lock/.gitignore | 3 - src/Symfony/Component/Lock/CHANGELOG.md | 7 - .../Lock/Exception/ExceptionInterface.php | 21 -- .../Exception/InvalidArgumentException.php | 19 - .../Lock/Exception/LockAcquiringException.php | 21 -- .../Exception/LockConflictedException.php | 21 -- .../Lock/Exception/LockReleasingException.php | 21 -- .../Lock/Exception/LockStorageException.php | 21 -- .../Lock/Exception/NotSupportedException.php | 21 -- src/Symfony/Component/Lock/Factory.php | 51 --- src/Symfony/Component/Lock/Key.php | 73 ---- src/Symfony/Component/Lock/LICENSE | 19 - src/Symfony/Component/Lock/Lock.php | 123 ------ src/Symfony/Component/Lock/LockInterface.php | 59 --- src/Symfony/Component/Lock/README.md | 11 - .../Component/Lock/Store/CombinedStore.php | 174 --------- .../Component/Lock/Store/FlockStore.php | 138 ------- .../Component/Lock/Store/MemcachedStore.php | 179 --------- .../Component/Lock/Store/RedisStore.php | 156 -------- .../Lock/Store/RetryTillSaveStore.php | 102 ----- .../Component/Lock/Store/SemaphoreStore.php | 112 ------ src/Symfony/Component/Lock/StoreInterface.php | 73 ---- .../Lock/Strategy/ConsensusStrategy.php | 36 -- .../Lock/Strategy/StrategyInterface.php | 43 --- .../Lock/Strategy/UnanimousStrategy.php | 36 -- .../Component/Lock/Tests/FactoryTest.php | 36 -- src/Symfony/Component/Lock/Tests/LockTest.php | 156 -------- .../Tests/Store/AbstractRedisStoreTest.php | 45 --- .../Lock/Tests/Store/AbstractStoreTest.php | 112 ------ .../Tests/Store/BlockingStoreTestTrait.php | 81 ---- .../Lock/Tests/Store/CombinedStoreTest.php | 356 ------------------ .../Tests/Store/ExpiringStoreTestTrait.php | 78 ---- .../Lock/Tests/Store/FlockStoreTest.php | 77 ---- .../Lock/Tests/Store/MemcachedStoreTest.php | 52 --- .../Lock/Tests/Store/PredisStoreTest.php | 36 -- .../Lock/Tests/Store/RedisArrayStoreTest.php | 38 -- .../Lock/Tests/Store/RedisStoreTest.php | 36 -- .../Tests/Store/RetryTillSaveStoreTest.php | 35 -- .../Lock/Tests/Store/SemaphoreStoreTest.php | 36 -- .../Tests/Strategy/ConsensusStrategyTest.php | 89 ----- .../Tests/Strategy/UnanimousStrategyTest.php | 89 ----- src/Symfony/Component/Lock/composer.json | 38 -- src/Symfony/Component/Lock/phpunit.xml.dist | 32 -- 44 files changed, 2963 deletions(-) delete mode 100644 src/Symfony/Component/Lock/.gitignore delete mode 100644 src/Symfony/Component/Lock/CHANGELOG.md delete mode 100644 src/Symfony/Component/Lock/Exception/ExceptionInterface.php delete mode 100644 src/Symfony/Component/Lock/Exception/InvalidArgumentException.php delete mode 100644 src/Symfony/Component/Lock/Exception/LockAcquiringException.php delete mode 100644 src/Symfony/Component/Lock/Exception/LockConflictedException.php delete mode 100644 src/Symfony/Component/Lock/Exception/LockReleasingException.php delete mode 100644 src/Symfony/Component/Lock/Exception/LockStorageException.php delete mode 100644 src/Symfony/Component/Lock/Exception/NotSupportedException.php delete mode 100644 src/Symfony/Component/Lock/Factory.php delete mode 100644 src/Symfony/Component/Lock/Key.php delete mode 100644 src/Symfony/Component/Lock/LICENSE delete mode 100644 src/Symfony/Component/Lock/Lock.php delete mode 100644 src/Symfony/Component/Lock/LockInterface.php delete mode 100644 src/Symfony/Component/Lock/README.md delete mode 100644 src/Symfony/Component/Lock/Store/CombinedStore.php delete mode 100644 src/Symfony/Component/Lock/Store/FlockStore.php delete mode 100644 src/Symfony/Component/Lock/Store/MemcachedStore.php delete mode 100644 src/Symfony/Component/Lock/Store/RedisStore.php delete mode 100644 src/Symfony/Component/Lock/Store/RetryTillSaveStore.php delete mode 100644 src/Symfony/Component/Lock/Store/SemaphoreStore.php delete mode 100644 src/Symfony/Component/Lock/StoreInterface.php delete mode 100644 src/Symfony/Component/Lock/Strategy/ConsensusStrategy.php delete mode 100644 src/Symfony/Component/Lock/Strategy/StrategyInterface.php delete mode 100644 src/Symfony/Component/Lock/Strategy/UnanimousStrategy.php delete mode 100644 src/Symfony/Component/Lock/Tests/FactoryTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/LockTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/AbstractRedisStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/CombinedStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/FlockStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/PredisStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/RedisArrayStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/RedisStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/RetryTillSaveStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php delete mode 100644 src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php delete mode 100644 src/Symfony/Component/Lock/composer.json delete mode 100644 src/Symfony/Component/Lock/phpunit.xml.dist diff --git a/composer.json b/composer.json index 42be8e2b4ee41..13ad97446582a 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,6 @@ "symfony/inflector": "self.version", "symfony/intl": "self.version", "symfony/ldap": "self.version", - "symfony/lock": "self.version", "symfony/monolog-bridge": "self.version", "symfony/options-resolver": "self.version", "symfony/process": "self.version", diff --git a/src/Symfony/Component/Lock/.gitignore b/src/Symfony/Component/Lock/.gitignore deleted file mode 100644 index 5414c2c655e72..0000000000000 --- a/src/Symfony/Component/Lock/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -composer.lock -phpunit.xml -vendor/ diff --git a/src/Symfony/Component/Lock/CHANGELOG.md b/src/Symfony/Component/Lock/CHANGELOG.md deleted file mode 100644 index 2204282c26ca6..0000000000000 --- a/src/Symfony/Component/Lock/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -CHANGELOG -========= - -3.3.0 ------ - - * added the component diff --git a/src/Symfony/Component/Lock/Exception/ExceptionInterface.php b/src/Symfony/Component/Lock/Exception/ExceptionInterface.php deleted file mode 100644 index 0d41958474061..0000000000000 --- a/src/Symfony/Component/Lock/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * Base ExceptionInterface for the Lock Component. - * - * @author Jérémy Derussé - */ -interface ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/InvalidArgumentException.php b/src/Symfony/Component/Lock/Exception/InvalidArgumentException.php deleted file mode 100644 index f2f74b37ce324..0000000000000 --- a/src/Symfony/Component/Lock/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,19 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * @author Jérémy Derussé - */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/LockAcquiringException.php b/src/Symfony/Component/Lock/Exception/LockAcquiringException.php deleted file mode 100644 index e6756aec14fcd..0000000000000 --- a/src/Symfony/Component/Lock/Exception/LockAcquiringException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * LockAcquiringException is thrown when an issue happens during the acquisition of a lock. - * - * @author Jérémy Derussé - */ -class LockAcquiringException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/LockConflictedException.php b/src/Symfony/Component/Lock/Exception/LockConflictedException.php deleted file mode 100644 index 8fcd6a836d217..0000000000000 --- a/src/Symfony/Component/Lock/Exception/LockConflictedException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * LockConflictedException is thrown when a lock is acquired by someone else. - * - * @author Jérémy Derussé - */ -class LockConflictedException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/LockReleasingException.php b/src/Symfony/Component/Lock/Exception/LockReleasingException.php deleted file mode 100644 index 56eedde79eb43..0000000000000 --- a/src/Symfony/Component/Lock/Exception/LockReleasingException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * LockReleasingException is thrown when an issue happens during the release of a lock. - * - * @author Jérémy Derussé - */ -class LockReleasingException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/LockStorageException.php b/src/Symfony/Component/Lock/Exception/LockStorageException.php deleted file mode 100644 index 8c393fc1bd509..0000000000000 --- a/src/Symfony/Component/Lock/Exception/LockStorageException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * LockStorageException is thrown when an issue happens during the manipulation of a lock in a store. - * - * @author Jérémy Derussé - */ -class LockStorageException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Exception/NotSupportedException.php b/src/Symfony/Component/Lock/Exception/NotSupportedException.php deleted file mode 100644 index c9a7f013c11aa..0000000000000 --- a/src/Symfony/Component/Lock/Exception/NotSupportedException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Exception; - -/** - * NotSupportedException is thrown when an unsupported method is called. - * - * @author Jérémy Derussé - */ -class NotSupportedException extends \LogicException implements ExceptionInterface -{ -} diff --git a/src/Symfony/Component/Lock/Factory.php b/src/Symfony/Component/Lock/Factory.php deleted file mode 100644 index c050145f90978..0000000000000 --- a/src/Symfony/Component/Lock/Factory.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock; - -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\NullLogger; - -/** - * Factory provides method to create locks. - * - * @author Jérémy Derussé - */ -class Factory implements LoggerAwareInterface -{ - use LoggerAwareTrait; - - private $store; - - public function __construct(StoreInterface $store) - { - $this->store = $store; - - $this->logger = new NullLogger(); - } - - /** - * Creates a lock for the given resource. - * - * @param string $resource The resource to lock - * @param float $ttl maximum expected lock duration - * - * @return Lock - */ - public function createLock($resource, $ttl = 300.0) - { - $lock = new Lock(new Key($resource), $this->store, $ttl); - $lock->setLogger($this->logger); - - return $lock; - } -} diff --git a/src/Symfony/Component/Lock/Key.php b/src/Symfony/Component/Lock/Key.php deleted file mode 100644 index 5b53ae9b6b078..0000000000000 --- a/src/Symfony/Component/Lock/Key.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock; - -/** - * Key is a container for the state of the locks in stores. - * - * @author Jérémy Derussé - */ -final class Key -{ - private $resource; - private $state = array(); - - /** - * @param string $resource - */ - public function __construct($resource) - { - $this->resource = (string) $resource; - } - - public function __toString() - { - return $this->resource; - } - - /** - * @param string $stateKey - * - * @return bool - */ - public function hasState($stateKey) - { - return isset($this->state[$stateKey]); - } - - /** - * @param string $stateKey - * @param mixed $state - */ - public function setState($stateKey, $state) - { - $this->state[$stateKey] = $state; - } - - /** - * @param string $stateKey - */ - public function removeState($stateKey) - { - unset($this->state[$stateKey]); - } - - /** - * @param $stateKey - * - * @return mixed - */ - public function getState($stateKey) - { - return $this->state[$stateKey]; - } -} diff --git a/src/Symfony/Component/Lock/LICENSE b/src/Symfony/Component/Lock/LICENSE deleted file mode 100644 index ce39894f6a9a2..0000000000000 --- a/src/Symfony/Component/Lock/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2016-2017 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/Symfony/Component/Lock/Lock.php b/src/Symfony/Component/Lock/Lock.php deleted file mode 100644 index 5d5342a528002..0000000000000 --- a/src/Symfony/Component/Lock/Lock.php +++ /dev/null @@ -1,123 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock; - -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\NullLogger; -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockAcquiringException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockReleasingException; - -/** - * Lock is the default implementation of the LockInterface. - * - * @author Jérémy Derussé - */ -final class Lock implements LockInterface, LoggerAwareInterface -{ - use LoggerAwareTrait; - - private $store; - private $key; - private $ttl; - - /** - * @param Key $key - * @param StoreInterface $store - * @param float|null $ttl - */ - public function __construct(Key $key, StoreInterface $store, $ttl = null) - { - $this->store = $store; - $this->key = $key; - $this->ttl = $ttl; - - $this->logger = new NullLogger(); - } - - /** - * {@inheritdoc} - */ - public function acquire($blocking = false) - { - try { - if (!$blocking) { - $this->store->save($this->key); - } else { - $this->store->waitAndSave($this->key); - } - - $this->logger->info('Successfully acquired the "{resource}" lock.', array('resource' => $this->key)); - - if ($this->ttl) { - $this->refresh(); - } - - return true; - } catch (LockConflictedException $e) { - $this->logger->warning('Failed to acquire the "{resource}" lock. Someone else already acquired the lock.', array('resource' => $this->key)); - - if ($blocking) { - throw $e; - } - - return false; - } catch (\Exception $e) { - $this->logger->warning('Failed to acquire the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); - throw new LockAcquiringException(sprintf('Failed to acquire the "%s" lock.', $this->key), 0, $e); - } - } - - /** - * {@inheritdoc} - */ - public function refresh() - { - if (!$this->ttl) { - throw new InvalidArgumentException('You have to define an expiration duration.'); - } - - try { - $this->store->putOffExpiration($this->key, $this->ttl); - $this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $this->ttl)); - } catch (LockConflictedException $e) { - $this->logger->warning('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock.', array('resource' => $this->key)); - throw $e; - } catch (\Exception $e) { - $this->logger->warning('Failed to define an expiration for the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); - throw new LockAcquiringException(sprintf('Failed to define an expiration for the "%s" lock.', $this->key), 0, $e); - } - } - - /** - * {@inheritdoc} - */ - public function isAcquired() - { - return $this->store->exists($this->key); - } - - /** - * {@inheritdoc} - */ - public function release() - { - $this->store->delete($this->key); - - if ($this->store->exists($this->key)) { - $this->logger->warning('Failed to release the "{resource}" lock.', array('resource' => $this->key)); - throw new LockReleasingException(sprintf('Failed to release the "%s" lock.', $this->key)); - } - } -} diff --git a/src/Symfony/Component/Lock/LockInterface.php b/src/Symfony/Component/Lock/LockInterface.php deleted file mode 100644 index ab05d7a8f4ab1..0000000000000 --- a/src/Symfony/Component/Lock/LockInterface.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock; - -use Symfony\Component\Lock\Exception\LockAcquiringException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockReleasingException; - -/** - * LockInterface defines an interface to manipulate the status of a lock. - * - * @author Jérémy Derussé - */ -interface LockInterface -{ - /** - * Acquires the lock. If the lock is acquired by someone else, the parameter `blocking` determines whether or not - * the the call should block until the release of the lock. - * - * @param bool $blocking Whether or not the Lock should wait for the release of someone else - * - * @return bool Whether or not the lock had been acquired. - * - * @throws LockConflictedException If the lock is acquired by someone else in blocking mode - * @throws LockAcquiringException If the lock can not be acquired - */ - public function acquire($blocking = false); - - /** - * Increase the duration of an acquired lock. - * - * @throws LockConflictedException If the lock is acquired by someone else - * @throws LockAcquiringException If the lock can not be refreshed - */ - public function refresh(); - - /** - * Returns whether or not the lock is acquired. - * - * @return bool - */ - public function isAcquired(); - - /** - * Release the lock. - * - * @throws LockReleasingException If the lock can not be released - */ - public function release(); -} diff --git a/src/Symfony/Component/Lock/README.md b/src/Symfony/Component/Lock/README.md deleted file mode 100644 index 0be0bfd49dfda..0000000000000 --- a/src/Symfony/Component/Lock/README.md +++ /dev/null @@ -1,11 +0,0 @@ -Lock Component -============== - -Resources ---------- - - * [Documentation](https://symfony.com/doc/master/components/lock.html) - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Lock/Store/CombinedStore.php b/src/Symfony/Component/Lock/Store/CombinedStore.php deleted file mode 100644 index 0f5a78cef6455..0000000000000 --- a/src/Symfony/Component/Lock/Store/CombinedStore.php +++ /dev/null @@ -1,174 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\NullLogger; -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\NotSupportedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\Strategy\StrategyInterface; -use Symfony\Component\Lock\StoreInterface; - -/** - * CombinedStore is a StoreInterface implementation able to manage and synchronize several StoreInterfaces. - * - * @author Jérémy Derussé - */ -class CombinedStore implements StoreInterface, LoggerAwareInterface -{ - use LoggerAwareTrait; - - /** @var StoreInterface[] */ - private $stores; - /** @var StrategyInterface */ - private $strategy; - - /** - * @param StoreInterface[] $stores The list of synchronized stores - * @param StrategyInterface $strategy - * - * @throws InvalidArgumentException - */ - public function __construct(array $stores, StrategyInterface $strategy) - { - foreach ($stores as $store) { - if (!$store instanceof StoreInterface) { - throw new InvalidArgumentException(sprintf('The store must implement "%s". Got "%s".', StoreInterface::class, get_class($store))); - } - } - - $this->stores = $stores; - $this->strategy = $strategy; - $this->logger = new NullLogger(); - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $successCount = 0; - $failureCount = 0; - $storesCount = count($this->stores); - - foreach ($this->stores as $store) { - try { - $store->save($key); - ++$successCount; - } catch (\Exception $e) { - $this->logger->warning('One store failed to save the "{resource}" lock.', array('resource' => $key, 'store' => $store, 'exception' => $e)); - ++$failureCount; - } - - if (!$this->strategy->canBeMet($failureCount, $storesCount)) { - break; - } - } - - if ($this->strategy->isMet($successCount, $storesCount)) { - return; - } - - $this->logger->warning('Failed to store the "{resource}" lock. Quorum has not been met.', array('resource' => $key, 'success' => $successCount, 'failure' => $failureCount)); - - // clean up potential locks - $this->delete($key); - - throw new LockConflictedException(); - } - - public function waitAndSave(Key $key) - { - throw new NotSupportedException(sprintf('The store "%s" does not supports blocking locks.', get_class($this))); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - $successCount = 0; - $failureCount = 0; - $storesCount = count($this->stores); - - foreach ($this->stores as $store) { - try { - $store->putOffExpiration($key, $ttl); - ++$successCount; - } catch (\Exception $e) { - $this->logger->warning('One store failed to put off the expiration of the "{resource}" lock.', array('resource' => $key, 'store' => $store, 'exception' => $e)); - ++$failureCount; - } - - if (!$this->strategy->canBeMet($failureCount, $storesCount)) { - break; - } - } - - if ($this->strategy->isMet($successCount, $storesCount)) { - return; - } - - $this->logger->warning('Failed to define the expiration for the "{resource}" lock. Quorum has not been met.', array('resource' => $key, 'success' => $successCount, 'failure' => $failureCount)); - - // clean up potential locks - $this->delete($key); - - throw new LockConflictedException(); - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - foreach ($this->stores as $store) { - try { - $store->delete($key); - } catch (\Exception $e) { - $this->logger->notice('One store failed to delete the "{resource}" lock.', array('resource' => $key, 'store' => $store, 'exception' => $e)); - } catch (\Throwable $e) { - $this->logger->notice('One store failed to delete the "{resource}" lock.', array('resource' => $key, 'store' => $store, 'exception' => $e)); - } - } - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - $successCount = 0; - $failureCount = 0; - $storesCount = count($this->stores); - - foreach ($this->stores as $store) { - if ($store->exists($key)) { - ++$successCount; - } else { - ++$failureCount; - } - - if ($this->strategy->isMet($successCount, $storesCount)) { - return true; - } - if (!$this->strategy->canBeMet($failureCount, $storesCount)) { - return false; - } - } - - return false; - } -} diff --git a/src/Symfony/Component/Lock/Store/FlockStore.php b/src/Symfony/Component/Lock/Store/FlockStore.php deleted file mode 100644 index 6bd28c83a42e8..0000000000000 --- a/src/Symfony/Component/Lock/Store/FlockStore.php +++ /dev/null @@ -1,138 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\LockStorageException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * FlockStore is a StoreInterface implementation using the FileSystem flock. - * - * Original implementation in \Symfony\Component\Filesystem\LockHandler. - * - * @author Jérémy Derussé - * @author Grégoire Pineau - * @author Romain Neutron - * @author Nicolas Grekas - */ -class FlockStore implements StoreInterface -{ - private $lockPath; - - /** - * @param string $lockPath the directory to store the lock - * - * @throws LockStorageException If the lock directory could not be created or is not writable - */ - public function __construct($lockPath) - { - if (!is_dir($lockPath) || !is_writable($lockPath)) { - throw new InvalidArgumentException(sprintf('The directory "%s" is not writable.', $lockPath)); - } - - $this->lockPath = $lockPath; - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $this->lock($key, false); - } - - /** - * {@inheritdoc} - */ - public function waitAndSave(Key $key) - { - $this->lock($key, true); - } - - private function lock(Key $key, $blocking) - { - // The lock is maybe already acquired. - if ($key->hasState(__CLASS__)) { - return; - } - - $fileName = sprintf('%s/sf.%s.%s.lock', - $this->lockPath, - preg_replace('/[^a-z0-9\._-]+/i', '-', $key), - hash('sha256', $key) - ); - - // Silence error reporting - set_error_handler(function () { - }); - if (!$handle = fopen($fileName, 'r')) { - if ($handle = fopen($fileName, 'x')) { - chmod($fileName, 0444); - } elseif (!$handle = fopen($fileName, 'r')) { - usleep(100); // Give some time for chmod() to complete - $handle = fopen($fileName, 'r'); - } - } - restore_error_handler(); - - if (!$handle) { - $error = error_get_last(); - throw new LockStorageException($error['message'], 0, null); - } - - // On Windows, even if PHP doc says the contrary, LOCK_NB works, see - // https://bugs.php.net/54129 - if (!flock($handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) { - fclose($handle); - throw new LockConflictedException(); - } - - $key->setState(__CLASS__, $handle); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - // do nothing, the flock locks forever. - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - // The lock is maybe not acquired. - if (!$key->hasState(__CLASS__)) { - return; - } - - $handle = $key->getState(__CLASS__); - - flock($handle, LOCK_UN | LOCK_NB); - fclose($handle); - - $key->removeState(__CLASS__); - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - return $key->hasState(__CLASS__); - } -} diff --git a/src/Symfony/Component/Lock/Store/MemcachedStore.php b/src/Symfony/Component/Lock/Store/MemcachedStore.php deleted file mode 100644 index a1e31ee63320f..0000000000000 --- a/src/Symfony/Component/Lock/Store/MemcachedStore.php +++ /dev/null @@ -1,179 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * MemcachedStore is a StoreInterface implementation using Memcached as store engine. - * - * @author Jérémy Derussé - */ -class MemcachedStore implements StoreInterface -{ - private $memcached; - private $initialTtl; - /** @var bool */ - private $useExtendedReturn; - - public static function isSupported() - { - return extension_loaded('memcached'); - } - - /** - * @param \Memcached $memcached - * @param int $initialTtl the expiration delay of locks in seconds - */ - public function __construct(\Memcached $memcached, $initialTtl = 300) - { - if (!static::isSupported()) { - throw new InvalidArgumentException('Memcached extension is required'); - } - - if ($initialTtl < 1) { - throw new InvalidArgumentException(sprintf('%s() expects a strictly positive TTL. Got %d.', __METHOD__, $initialTtl)); - } - - $this->memcached = $memcached; - $this->initialTtl = $initialTtl; - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $token = $this->getToken($key); - - if ($this->memcached->add((string) $key, $token, (int) ceil($this->initialTtl))) { - return; - } - - // the lock is already acquire. It could be us. Let's try to put off. - $this->putOffExpiration($key, $this->initialTtl); - } - - public function waitAndSave(Key $key) - { - throw new InvalidArgumentException(sprintf('The store "%s" does not supports blocking locks.', get_class($this))); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - if ($ttl < 1) { - throw new InvalidArgumentException(sprintf('%s() expects a TTL greater or equals to 1. Got %s.', __METHOD__, $ttl)); - } - - // Interface defines a float value but Store required an integer. - $ttl = (int) ceil($ttl); - - $token = $this->getToken($key); - - list($value, $cas) = $this->getValueAndCas($key); - - // 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(); - } - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - $token = $this->getToken($key); - - list($value, $cas) = $this->getValueAndCas($key); - - if ($value !== $token) { - // we are not the owner of the lock. Nothing to do. - return; - } - - // To avoid concurrency in deletion, the trick is to extends the TTL then deleting the key - if (!$this->memcached->cas($cas, (string) $key, $token, 2)) { - // Someone steal our lock. It does not belongs to us anymore. Nothing to do. - return; - } - - // Now, we are the owner of the lock for 2 more seconds, we can delete it. - $this->memcached->delete((string) $key); - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - return $this->memcached->get((string) $key) === $this->getToken($key); - } - - /** - * Retrieve an unique token for the given key. - * - * @param Key $key - * - * @return string - */ - private function getToken(Key $key) - { - if (!$key->hasState(__CLASS__)) { - $token = base64_encode(random_bytes(32)); - $key->setState(__CLASS__, $token); - } - - return $key->getState(__CLASS__); - } - - private function getValueAndCas(Key $key) - { - if (null === $this->useExtendedReturn) { - $this->useExtendedReturn = version_compare(phpversion('memcached'), '2.9.9', '>'); - } - - if ($this->useExtendedReturn) { - $extendedReturn = $this->memcached->get((string) $key, null, \Memcached::GET_EXTENDED); - if ($extendedReturn === \Memcached::GET_ERROR_RETURN_VALUE) { - return array($extendedReturn, 0.0); - } - - return array($extendedReturn['value'], $extendedReturn['cas']); - } - - $cas = 0.0; - $value = $this->memcached->get((string) $key, null, $cas); - - return array($value, $cas); - } -} diff --git a/src/Symfony/Component/Lock/Store/RedisStore.php b/src/Symfony/Component/Lock/Store/RedisStore.php deleted file mode 100644 index b9ea2a5fb80e3..0000000000000 --- a/src/Symfony/Component/Lock/Store/RedisStore.php +++ /dev/null @@ -1,156 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * RedisStore is a StoreInterface implementation using Redis as store engine. - * - * @author Jérémy Derussé - */ -class RedisStore implements StoreInterface -{ - private $redis; - private $initialTtl; - - /** - * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient - * @param float $initialTtl the expiration delay of locks in seconds - */ - public function __construct($redisClient, $initialTtl = 300.0) - { - if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client) { - throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($redisClient) ? get_class($redisClient) : gettype($redisClient))); - } - - if ($initialTtl <= 0) { - throw new InvalidArgumentException(sprintf('%s() expects a strictly positive TTL. Got %d.', __METHOD__, $initialTtl)); - } - - $this->redis = $redisClient; - $this->initialTtl = $initialTtl; - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $script = ' - if redis.call("GET", KEYS[1]) == ARGV[1] then - return redis.call("PEXPIRE", KEYS[1], ARGV[2]) - else - return redis.call("set", KEYS[1], ARGV[1], "NX", "PX", ARGV[2]) - end - '; - - $expire = (int) ceil($this->initialTtl * 1000); - if (!$this->evaluate($script, (string) $key, array($this->getToken($key), $expire))) { - throw new LockConflictedException(); - } - } - - public function waitAndSave(Key $key) - { - throw new InvalidArgumentException(sprintf('The store "%s" does not supports blocking locks.', get_class($this))); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - $script = ' - if redis.call("GET", KEYS[1]) == ARGV[1] then - return redis.call("PEXPIRE", KEYS[1], ARGV[2]) - else - return 0 - end - '; - - $expire = (int) ceil($ttl * 1000); - if (!$this->evaluate($script, (string) $key, array($this->getToken($key), $expire))) { - throw new LockConflictedException(); - } - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - $script = ' - if redis.call("GET", KEYS[1]) == ARGV[1] then - return redis.call("DEL", KEYS[1]) - else - return 0 - end - '; - - $this->evaluate($script, (string) $key, array($this->getToken($key))); - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - return $this->redis->get((string) $key) === $this->getToken($key); - } - - /** - * Evaluates a script in the corresponding redis client. - * - * @param string $script - * @param string $resource - * @param array $args - * - * @return mixed - */ - private function evaluate($script, $resource, array $args) - { - if ($this->redis instanceof \Redis || $this->redis instanceof \RedisCluster) { - return $this->redis->eval($script, array_merge(array($resource), $args), 1); - } - - if ($this->redis instanceof \RedisArray) { - return $this->redis->_instance($this->redis->_target($resource))->eval($script, array_merge(array($resource), $args), 1); - } - - if ($this->redis instanceof \Predis\Client) { - return call_user_func_array(array($this->redis, 'eval'), array_merge(array($script, 1, $resource), $args)); - } - - throw new InvalidArgumentException(sprintf('%s() expects been initialized with a Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($this->redis) ? get_class($this->redis) : gettype($this->redis))); - } - - /** - * Retrieves an unique token for the given key. - * - * @param Key $key - * - * @return string - */ - private function getToken(Key $key) - { - if (!$key->hasState(__CLASS__)) { - $token = base64_encode(random_bytes(32)); - $key->setState(__CLASS__, $token); - } - - return $key->getState(__CLASS__); - } -} diff --git a/src/Symfony/Component/Lock/Store/RetryTillSaveStore.php b/src/Symfony/Component/Lock/Store/RetryTillSaveStore.php deleted file mode 100644 index dfc3b266687d9..0000000000000 --- a/src/Symfony/Component/Lock/Store/RetryTillSaveStore.php +++ /dev/null @@ -1,102 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\NullLogger; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * RetryTillSaveStore is a StoreInterface implementation which decorate a non blocking StoreInterface to provide a - * blocking storage. - * - * @author Jérémy Derussé - */ -class RetryTillSaveStore implements StoreInterface, LoggerAwareInterface -{ - use LoggerAwareTrait; - - private $decorated; - private $retrySleep; - private $retryCount; - - /** - * @param StoreInterface $decorated The decorated StoreInterface - * @param int $retrySleep Duration in ms between 2 retry - * @param int $retryCount Maximum amount of retry - */ - public function __construct(StoreInterface $decorated, $retrySleep = 100, $retryCount = PHP_INT_MAX) - { - $this->decorated = $decorated; - $this->retrySleep = $retrySleep; - $this->retryCount = $retryCount; - - $this->logger = new NullLogger(); - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $this->decorated->save($key); - } - - /** - * {@inheritdoc} - */ - public function waitAndSave(Key $key) - { - $retry = 0; - $sleepRandomness = (int) ($this->retrySleep / 10); - do { - try { - $this->decorated->save($key); - - return; - } catch (LockConflictedException $e) { - usleep(($this->retrySleep + random_int(-$sleepRandomness, $sleepRandomness)) * 1000); - } - } while (++$retry < $this->retryCount); - - $this->logger->warning('Failed to store the "{resource}" lock. Abort after {retry} retry.', array('resource' => $key, 'retry' => $retry)); - - throw new LockConflictedException(); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - $this->decorated->putOffExpiration($key, $ttl); - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - $this->decorated->delete($key); - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - return $this->decorated->exists($key); - } -} diff --git a/src/Symfony/Component/Lock/Store/SemaphoreStore.php b/src/Symfony/Component/Lock/Store/SemaphoreStore.php deleted file mode 100644 index 986c33b6e9c56..0000000000000 --- a/src/Symfony/Component/Lock/Store/SemaphoreStore.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Store; - -use Symfony\Component\Lock\Exception\InvalidArgumentException; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\NotSupportedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * SemaphoreStore is a StoreInterface implementation using Semaphore as store engine. - * - * @author Jérémy Derussé - */ -class SemaphoreStore implements StoreInterface -{ - public static function isSupported() - { - return extension_loaded('sysvsem'); - } - - public function __construct() - { - if (!static::isSupported()) { - throw new InvalidArgumentException('Semaphore extension (sysvsem) is required'); - } - } - - /** - * {@inheritdoc} - */ - public function save(Key $key) - { - $this->lock($key, false); - } - - /** - * {@inheritdoc} - */ - public function waitAndSave(Key $key) - { - $this->lock($key, true); - } - - private function lock(Key $key, $blocking) - { - if ($key->hasState(__CLASS__)) { - return; - } - - $resource = sem_get(crc32($key)); - - if (PHP_VERSION_ID < 50601) { - if (!$blocking) { - throw new NotSupportedException(sprintf('The store "%s" does not supports non blocking locks.', get_class($this))); - } - - $acquired = sem_acquire($resource); - } else { - $acquired = sem_acquire($resource, !$blocking); - } - - if (!$acquired) { - throw new LockConflictedException(); - } - - $key->setState(__CLASS__, $resource); - } - - /** - * {@inheritdoc} - */ - public function delete(Key $key) - { - // The lock is maybe not acquired. - if (!$key->hasState(__CLASS__)) { - return; - } - - $resource = $key->getState(__CLASS__); - - sem_release($resource); - - $key->removeState(__CLASS__); - } - - /** - * {@inheritdoc} - */ - public function putOffExpiration(Key $key, $ttl) - { - // do nothing, the flock locks forever. - } - - /** - * {@inheritdoc} - */ - public function exists(Key $key) - { - return $key->hasState(__CLASS__); - } -} diff --git a/src/Symfony/Component/Lock/StoreInterface.php b/src/Symfony/Component/Lock/StoreInterface.php deleted file mode 100644 index 428786b4c8bf6..0000000000000 --- a/src/Symfony/Component/Lock/StoreInterface.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock; - -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Exception\NotSupportedException; - -/** - * StoreInterface defines an interface to manipulate a lock store. - * - * @author Jérémy Derussé - */ -interface StoreInterface -{ - /** - * Stores the resource if it's not locked by someone else. - * - * @param Key $key key to lock - * - * @throws LockConflictedException - */ - public function save(Key $key); - - /** - * Waits a key becomes free, then stores the resource. - * - * If the store does not support this feature it should throw a NotSupportedException. - * - * @param Key $key key to lock - * - * @throws LockConflictedException - * @throws NotSupportedException - */ - public function waitAndSave(Key $key); - - /** - * Extends the ttl of a resource. - * - * If the store does not support this feature it should throw a NotSupportedException. - * - * @param Key $key key to lock - * @param float $ttl amount of second to keep the lock in the store - * - * @throws LockConflictedException - * @throws NotSupportedException - */ - public function putOffExpiration(Key $key, $ttl); - - /** - * Removes a resource from the storage. - * - * @param Key $key key to remove - */ - public function delete(Key $key); - - /** - * Returns whether or not the resource exists in the storage. - * - * @param Key $key key to remove - * - * @return bool - */ - public function exists(Key $key); -} diff --git a/src/Symfony/Component/Lock/Strategy/ConsensusStrategy.php b/src/Symfony/Component/Lock/Strategy/ConsensusStrategy.php deleted file mode 100644 index 047820a409f1d..0000000000000 --- a/src/Symfony/Component/Lock/Strategy/ConsensusStrategy.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Strategy; - -/** - * ConsensusStrategy is a StrategyInterface implementation where strictly more than 50% items should be successful. - * - * @author Jérémy Derussé - */ -class ConsensusStrategy implements StrategyInterface -{ - /** - * {@inheritdoc} - */ - public function isMet($numberOfSuccess, $numberOfItems) - { - return $numberOfSuccess > ($numberOfItems / 2); - } - - /** - * {@inheritdoc} - */ - public function canBeMet($numberOfFailure, $numberOfItems) - { - return $numberOfFailure < ($numberOfItems / 2); - } -} diff --git a/src/Symfony/Component/Lock/Strategy/StrategyInterface.php b/src/Symfony/Component/Lock/Strategy/StrategyInterface.php deleted file mode 100644 index beaa7280a2d49..0000000000000 --- a/src/Symfony/Component/Lock/Strategy/StrategyInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Strategy; - -/** - * StrategyInterface defines an interface to indicate when a quorum is met and can be met. - * - * @author Jérémy Derussé - */ -interface StrategyInterface -{ - /** - * Returns whether or not the quorum is met. - * - * @param int $numberOfSuccess - * @param int $numberOfItems - * - * @return bool - */ - public function isMet($numberOfSuccess, $numberOfItems); - - /** - * Returns whether or not the quorum *could* be met. - * - * This method does not mean the quorum *would* be met for sure, but can be useful to stop a process early when you - * known there is no chance to meet the quorum. - * - * @param int $numberOfFailure - * @param int $numberOfItems - * - * @return bool - */ - public function canBeMet($numberOfFailure, $numberOfItems); -} diff --git a/src/Symfony/Component/Lock/Strategy/UnanimousStrategy.php b/src/Symfony/Component/Lock/Strategy/UnanimousStrategy.php deleted file mode 100644 index 12d57e526ecf4..0000000000000 --- a/src/Symfony/Component/Lock/Strategy/UnanimousStrategy.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Strategy; - -/** - * UnanimousStrategy is a StrategyInterface implementation where 100% of elements should be successful. - * - * @author Jérémy Derussé - */ -class UnanimousStrategy implements StrategyInterface -{ - /** - * {@inheritdoc} - */ - public function isMet($numberOfSuccess, $numberOfItems) - { - return $numberOfSuccess === $numberOfItems; - } - - /** - * {@inheritdoc} - */ - public function canBeMet($numberOfFailure, $numberOfItems) - { - return $numberOfFailure === 0; - } -} diff --git a/src/Symfony/Component/Lock/Tests/FactoryTest.php b/src/Symfony/Component/Lock/Tests/FactoryTest.php deleted file mode 100644 index d67949098c7a4..0000000000000 --- a/src/Symfony/Component/Lock/Tests/FactoryTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests; - -use PHPUnit\Framework\TestCase; -use Psr\Log\LoggerInterface; -use Symfony\Component\Lock\Factory; -use Symfony\Component\Lock\LockInterface; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -class FactoryTest extends TestCase -{ - public function testCreateLock() - { - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $factory = new Factory($store); - $factory->setLogger($logger); - - $lock = $factory->createLock('foo'); - - $this->assertInstanceOf(LockInterface::class, $lock); - } -} diff --git a/src/Symfony/Component/Lock/Tests/LockTest.php b/src/Symfony/Component/Lock/Tests/LockTest.php deleted file mode 100644 index 58dbdc5820131..0000000000000 --- a/src/Symfony/Component/Lock/Tests/LockTest.php +++ /dev/null @@ -1,156 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\Lock; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -class LockTest extends TestCase -{ - public function testAcquireNoBlocking() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store); - - $store - ->expects($this->once()) - ->method('save'); - - $this->assertTrue($lock->acquire(false)); - } - - public function testAcquireReturnsFalse() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store); - - $store - ->expects($this->once()) - ->method('save') - ->willThrowException(new LockConflictedException()); - - $this->assertFalse($lock->acquire(false)); - } - - public function testAcquireBlocking() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store); - - $store - ->expects($this->never()) - ->method('save'); - $store - ->expects($this->once()) - ->method('waitAndSave'); - - $this->assertTrue($lock->acquire(true)); - } - - public function testAcquireSetsTtl() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store, 10); - - $store - ->expects($this->once()) - ->method('save'); - $store - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, 10); - - $lock->acquire(); - } - - public function testRefresh() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store, 10); - - $store - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, 10); - - $lock->refresh(); - } - - public function testIsAquired() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store, 10); - - $store - ->expects($this->once()) - ->method('exists') - ->with($key) - ->willReturn(true); - - $this->assertTrue($lock->isAcquired()); - } - - public function testRelease() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store, 10); - - $store - ->expects($this->once()) - ->method('delete') - ->with($key); - - $store - ->expects($this->once()) - ->method('exists') - ->with($key) - ->willReturn(false); - - $lock->release(); - } - - /** - * @expectedException \Symfony\Component\Lock\Exception\LockReleasingException - */ - public function testReleaseThrowsExceptionIfNotWellDeleted() - { - $key = new Key(uniqid(__METHOD__, true)); - $store = $this->getMockBuilder(StoreInterface::class)->getMock(); - $lock = new Lock($key, $store, 10); - - $store - ->expects($this->once()) - ->method('delete') - ->with($key); - - $store - ->expects($this->once()) - ->method('exists') - ->with($key) - ->willReturn(true); - - $lock->release(); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/AbstractRedisStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/AbstractRedisStoreTest.php deleted file mode 100644 index 4b9c81bd8e8c2..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/AbstractRedisStoreTest.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Store\RedisStore; - -/** - * @author Jérémy Derussé - */ -abstract class AbstractRedisStoreTest extends AbstractStoreTest -{ - use ExpiringStoreTestTrait; - - /** - * {@inheritdoc} - */ - protected function getClockDelay() - { - return 250000; - } - - /** - * Return a RedisConnection. - * - * @return \Redis|\RedisArray|\RedisCluster|\Predis\Client - */ - abstract protected function getRedisConnection(); - - /** - * {@inheritdoc} - */ - public function getStore() - { - return new RedisStore($this->getRedisConnection()); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php deleted file mode 100644 index c0d758744ce1a..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -abstract class AbstractStoreTest extends TestCase -{ - /** - * @return StoreInterface; - */ - abstract protected function getStore(); - - public function testSave() - { - $store = $this->getStore(); - - $key = new Key(uniqid(__METHOD__, true)); - - $this->assertFalse($store->exists($key)); - $store->save($key); - $this->assertTrue($store->exists($key)); - $store->delete($key); - $this->assertFalse($store->exists($key)); - } - - public function testSaveWithDifferentResources() - { - $store = $this->getStore(); - - $key1 = new Key(uniqid(__METHOD__, true)); - $key2 = new Key(uniqid(__METHOD__, true)); - - $store->save($key1); - $this->assertTrue($store->exists($key1)); - $this->assertFalse($store->exists($key2)); - $store->save($key2); - - $this->assertTrue($store->exists($key1)); - $this->assertTrue($store->exists($key2)); - - $store->delete($key1); - $this->assertFalse($store->exists($key1)); - $store->delete($key2); - $this->assertFalse($store->exists($key2)); - } - - public function testSaveWithDifferentKeysOnSameResources() - { - $store = $this->getStore(); - - $resource = uniqid(__METHOD__, true); - $key1 = new Key($resource); - $key2 = new Key($resource); - - $store->save($key1); - $this->assertTrue($store->exists($key1)); - $this->assertFalse($store->exists($key2)); - - try { - $store->save($key2); - throw new \Exception('The store shouldn\'t save the second key'); - } catch (LockConflictedException $e) { - } - - // The failure of previous attempt should not impact the state of current locks - $this->assertTrue($store->exists($key1)); - $this->assertFalse($store->exists($key2)); - - $store->delete($key1); - $this->assertFalse($store->exists($key1)); - $this->assertFalse($store->exists($key2)); - - $store->save($key2); - $this->assertFalse($store->exists($key1)); - $this->assertTrue($store->exists($key2)); - - $store->delete($key2); - $this->assertFalse($store->exists($key1)); - $this->assertFalse($store->exists($key2)); - } - - public function testSaveTwice() - { - $store = $this->getStore(); - - $resource = uniqid(__METHOD__, true); - $key = new Key($resource); - - $store->save($key); - $store->save($key); - // just asserts it don't throw an exception - $this->addToAssertionCount(1); - - $store->delete($key); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php b/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php deleted file mode 100644 index c34a82abafcb6..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php +++ /dev/null @@ -1,81 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -trait BlockingStoreTestTrait -{ - /** - * @see AbstractStoreTest::getStore() - */ - abstract protected function getStore(); - - /** - * Tests blocking locks thanks to pcntl. - * - * This test is time sensible: the $clockDelay could be adjust. - * - * @requires extension pcntl - */ - public function testBlockingLocks() - { - // Amount a microsecond used to order async actions - $clockDelay = 50000; - - if (PHP_VERSION_ID < 50600 || defined('HHVM_VERSION_ID')) { - $this->markTestSkipped('The PHP engine does not keep resource in child forks'); - - return; - } - - /** @var StoreInterface $store */ - $store = $this->getStore(); - $key = new Key(uniqid(__METHOD__, true)); - - if ($childPID1 = pcntl_fork()) { - // give time to fork to start - usleep(2 * $clockDelay); - - try { - // This call should failed given the lock should already by acquired by the child #1 - $store->save($key); - $this->fail('The store saves a locked key.'); - } catch (LockConflictedException $e) { - } - - // 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($childPID1, $status1); - $this->assertSame(0, pcntl_wexitstatus($status1), 'The child process couldn\'t lock the resource'); - } else { - try { - $store->save($key); - // Wait 3 ClockDelay to let parent process to finish - usleep(3 * $clockDelay); - $store->delete($key); - exit(0); - } catch (\Exception $e) { - exit(1); - } - } - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/CombinedStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/CombinedStoreTest.php deleted file mode 100644 index debe06183dc35..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/CombinedStoreTest.php +++ /dev/null @@ -1,356 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Exception\LockConflictedException; -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\Strategy\UnanimousStrategy; -use Symfony\Component\Lock\Strategy\StrategyInterface; -use Symfony\Component\Lock\Store\CombinedStore; -use Symfony\Component\Lock\Store\RedisStore; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -class CombinedStoreTest extends AbstractStoreTest -{ - use ExpiringStoreTestTrait; - - /** - * {@inheritdoc} - */ - protected function getClockDelay() - { - return 250000; - } - - /** - * {@inheritdoc} - */ - public function getStore() - { - $redis = new \Predis\Client('tcp://'.getenv('REDIS_HOST').':6379'); - try { - $redis->connect(); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - - return new CombinedStore(array(new RedisStore($redis)), new UnanimousStrategy()); - } - - /** @var \PHPUnit_Framework_MockObject_MockObject */ - private $strategy; - /** @var \PHPUnit_Framework_MockObject_MockObject */ - private $store1; - /** @var \PHPUnit_Framework_MockObject_MockObject */ - private $store2; - /** @var CombinedStore */ - private $store; - - public function setup() - { - $this->strategy = $this->getMockBuilder(StrategyInterface::class)->getMock(); - $this->store1 = $this->getMockBuilder(StoreInterface::class)->getMock(); - $this->store2 = $this->getMockBuilder(StoreInterface::class)->getMock(); - - $this->store = new CombinedStore(array($this->store1, $this->store2), $this->strategy); - } - - /** - * @expectedException \Symfony\Component\Lock\Exception\LockConflictedException - */ - public function testSaveThrowsExceptionOnFailure() - { - $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 - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - $this->store->save($key); - } - - public function testSaveCleanupOnFailure() - { - $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->store1 - ->expects($this->once()) - ->method('delete'); - $this->store2 - ->expects($this->once()) - ->method('delete'); - - $this->strategy - ->expects($this->any()) - ->method('canBeMet') - ->willReturn(true); - $this->strategy - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - try { - $this->store->save($key); - } catch (LockConflictedException $e) { - // Catch the exception given this is not what we want to assert in this tests - } - } - - public function testSaveAbortWhenStrategyCantBeMet() - { - $key = new Key(uniqid(__METHOD__, true)); - - $this->store1 - ->expects($this->once()) - ->method('save') - ->with($key) - ->willThrowException(new LockConflictedException()); - $this->store2 - ->expects($this->never()) - ->method('save'); - - $this->strategy - ->expects($this->once()) - ->method('canBeMet') - ->willReturn(false); - $this->strategy - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - try { - $this->store->save($key); - } catch (LockConflictedException $e) { - // Catch the exception given this is not what we want to assert in this tests - } - } - - /** - * @expectedException \Symfony\Component\Lock\Exception\LockConflictedException - */ - public function testputOffExpirationThrowsExceptionOnFailure() - { - $key = new Key(uniqid(__METHOD__, true)); - $ttl = random_int(1, 10); - - $this->store1 - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, $ttl) - ->willThrowException(new LockConflictedException()); - $this->store2 - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, $ttl) - ->willThrowException(new LockConflictedException()); - - $this->strategy - ->expects($this->any()) - ->method('canBeMet') - ->willReturn(true); - $this->strategy - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - $this->store->putOffExpiration($key, $ttl); - } - - public function testputOffExpirationCleanupOnFailure() - { - $key = new Key(uniqid(__METHOD__, true)); - $ttl = random_int(1, 10); - - $this->store1 - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, $ttl) - ->willThrowException(new LockConflictedException()); - $this->store2 - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, $ttl) - ->willThrowException(new LockConflictedException()); - - $this->store1 - ->expects($this->once()) - ->method('delete'); - $this->store2 - ->expects($this->once()) - ->method('delete'); - - $this->strategy - ->expects($this->any()) - ->method('canBeMet') - ->willReturn(true); - $this->strategy - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - try { - $this->store->putOffExpiration($key, $ttl); - } catch (LockConflictedException $e) { - // Catch the exception given this is not what we want to assert in this tests - } - } - - public function testputOffExpirationAbortWhenStrategyCantBeMet() - { - $key = new Key(uniqid(__METHOD__, true)); - $ttl = random_int(1, 10); - - $this->store1 - ->expects($this->once()) - ->method('putOffExpiration') - ->with($key, $ttl) - ->willThrowException(new LockConflictedException()); - $this->store2 - ->expects($this->never()) - ->method('putOffExpiration'); - - $this->strategy - ->expects($this->once()) - ->method('canBeMet') - ->willReturn(false); - $this->strategy - ->expects($this->any()) - ->method('isMet') - ->willReturn(false); - - try { - $this->store->putOffExpiration($key, $ttl); - } catch (LockConflictedException $e) { - // Catch the exception given this is not what we want to assert in this tests - } - } - - public function testPutOffExpirationIgnoreNonExpiringStorage() - { - $store1 = $this->getMockBuilder(StoreInterface::class)->getMock(); - $store2 = $this->getMockBuilder(StoreInterface::class)->getMock(); - - $store = new CombinedStore(array($store1, $store2), $this->strategy); - - $key = new Key(uniqid(__METHOD__, true)); - $ttl = random_int(1, 10); - - $this->strategy - ->expects($this->any()) - ->method('canBeMet') - ->willReturn(true); - $this->strategy - ->expects($this->once()) - ->method('isMet') - ->with(2, 2) - ->willReturn(true); - - $store->putOffExpiration($key, $ttl); - } - - public function testExistsDontAskToEveryBody() - { - $key = new Key(uniqid(__METHOD__, true)); - - $this->store1 - ->expects($this->any()) - ->method('exists') - ->with($key) - ->willReturn(false); - $this->store2 - ->expects($this->never()) - ->method('exists'); - - $this->strategy - ->expects($this->any()) - ->method('canBeMet') - ->willReturn(true); - $this->strategy - ->expects($this->once()) - ->method('isMet') - ->willReturn(true); - - $this->assertTrue($this->store->exists($key)); - } - - public function testExistsAbortWhenStrategyCantBeMet() - { - $key = new Key(uniqid(__METHOD__, true)); - - $this->store1 - ->expects($this->any()) - ->method('exists') - ->with($key) - ->willReturn(false); - $this->store2 - ->expects($this->never()) - ->method('exists'); - - $this->strategy - ->expects($this->once()) - ->method('canBeMet') - ->willReturn(false); - $this->strategy - ->expects($this->once()) - ->method('isMet') - ->willReturn(false); - - $this->assertFalse($this->store->exists($key)); - } - - public function testDeleteDontStopOnFailure() - { - $key = new Key(uniqid(__METHOD__, true)); - - $this->store1 - ->expects($this->once()) - ->method('delete') - ->with($key) - ->willThrowException(new \Exception()); - $this->store2 - ->expects($this->once()) - ->method('delete') - ->with($key); - - $this->store->delete($key); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php b/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php deleted file mode 100644 index 0280aa61739ee..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php +++ /dev/null @@ -1,78 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\StoreInterface; - -/** - * @author Jérémy Derussé - */ -trait ExpiringStoreTestTrait -{ - /** - * Amount a microsecond used to order async actions. - * - * @return int - */ - abstract protected function getClockDelay(); - - /** - * @see AbstractStoreTest::getStore() - */ - abstract protected function getStore(); - - /** - * Tests the store automatically delete the key when it expire. - * - * This test is time sensible: the $clockDelay could be adjust. - */ - public function testExpiration() - { - $key = new Key(uniqid(__METHOD__, true)); - $clockDelay = $this->getClockDelay(); - - /** @var StoreInterface $store */ - $store = $this->getStore(); - - $store->save($key); - $store->putOffExpiration($key, $clockDelay / 1000000); - $this->assertTrue($store->exists($key)); - - usleep(2 * $clockDelay); - $this->assertFalse($store->exists($key)); - } - - /** - * Tests the refresh can push the limits to the expiration. - * - * This test is time sensible: the $clockDelay could be adjust. - */ - public function testRefreshLock() - { - // Amount a microsecond used to order async actions - $clockDelay = $this->getClockDelay(); - - // Amount a microsecond used to order async actions - $key = new Key(uniqid(__METHOD__, true)); - - /** @var StoreInterface $store */ - $store = $this->getStore(); - - $store->save($key); - $store->putOffExpiration($key, 1.0 * $clockDelay / 1000000); - $this->assertTrue($store->exists($key)); - - usleep(2.1 * $clockDelay); - $this->assertFalse($store->exists($key)); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/FlockStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/FlockStoreTest.php deleted file mode 100644 index 17c59c440a9cc..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/FlockStoreTest.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Key; -use Symfony\Component\Lock\Store\FlockStore; - -/** - * @author Jérémy Derussé - */ -class FlockStoreTest extends AbstractStoreTest -{ - use BlockingStoreTestTrait; - - /** - * {@inheritdoc} - */ - protected function getStore() - { - return new FlockStore(sys_get_temp_dir()); - } - - /** - * @expectedException \Symfony\Component\Lock\Exception\InvalidArgumentException - * @expectedExceptionMessage The directory "/a/b/c/d/e" is not writable. - */ - public function testConstructWhenRepositoryDoesNotExist() - { - if (!getenv('USER') || 'root' === getenv('USER')) { - $this->markTestSkipped('This test will fail if run under superuser'); - } - - new FlockStore('/a/b/c/d/e'); - } - - /** - * @expectedException \Symfony\Component\Lock\Exception\InvalidArgumentException - * @expectedExceptionMessage The directory "/" is not writable. - */ - public function testConstructWhenRepositoryIsNotWriteable() - { - if (!getenv('USER') || 'root' === getenv('USER')) { - $this->markTestSkipped('This test will fail if run under superuser'); - } - - new FlockStore('/'); - } - - public function testSaveSanitizeName() - { - $store = $this->getStore(); - - $key = new Key(''); - - $file = sprintf( - '%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', - sys_get_temp_dir() - ); - // ensure the file does not exist before the store - @unlink($file); - - $store->save($key); - - $this->assertFileExists($file); - - $store->delete($key); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php deleted file mode 100644 index 72615baae2ce8..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Store\MemcachedStore; - -/** - * @author Jérémy Derussé - * - * @requires extension memcached - */ -class MemcachedStoreTest extends AbstractStoreTest -{ - use ExpiringStoreTestTrait; - - public static function setupBeforeClass() - { - $memcached = new \Memcached(); - $memcached->addServer(getenv('MEMCACHED_HOST'), 11211); - if (false === $memcached->getStats()) { - self::markTestSkipped('Unable to connect to the memcache host'); - } - } - - /** - * {@inheritdoc} - */ - protected function getClockDelay() - { - return 1000000; - } - - /** - * {@inheritdoc} - */ - public function getStore() - { - $memcached = new \Memcached(); - $memcached->addServer(getenv('MEMCACHED_HOST'), 11211); - - return new MemcachedStore($memcached); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/PredisStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/PredisStoreTest.php deleted file mode 100644 index 621affecb5435..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/PredisStoreTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -/** - * @author Jérémy Derussé - */ -class PredisStoreTest extends AbstractRedisStoreTest -{ - public static function setupBeforeClass() - { - $redis = new \Predis\Client('tcp://'.getenv('REDIS_HOST').':6379'); - try { - $redis->connect(); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - } - - protected function getRedisConnection() - { - $redis = new \Predis\Client('tcp://'.getenv('REDIS_HOST').':6379'); - $redis->connect(); - - return $redis; - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/RedisArrayStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/RedisArrayStoreTest.php deleted file mode 100644 index 180da4618da03..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/RedisArrayStoreTest.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -/** - * @author Jérémy Derussé - * - * @requires extension redis - */ -class RedisArrayStoreTest extends AbstractRedisStoreTest -{ - public static function setupBeforeClass() - { - if (!class_exists('RedisArray')) { - self::markTestSkipped('The RedisArray class is required.'); - } - if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) { - $e = error_get_last(); - self::markTestSkipped($e['message']); - } - } - - protected function getRedisConnection() - { - $redis = new \RedisArray(array(getenv('REDIS_HOST'))); - - return $redis; - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/RedisStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/RedisStoreTest.php deleted file mode 100644 index 6c7d244107b6d..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/RedisStoreTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -/** - * @author Jérémy Derussé - * - * @requires extension redis - */ -class RedisStoreTest extends AbstractRedisStoreTest -{ - public static function setupBeforeClass() - { - if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) { - $e = error_get_last(); - self::markTestSkipped($e['message']); - } - } - - protected function getRedisConnection() - { - $redis = new \Redis(); - $redis->connect(getenv('REDIS_HOST')); - - return $redis; - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/RetryTillSaveStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/RetryTillSaveStoreTest.php deleted file mode 100644 index febd48f279fc5..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/RetryTillSaveStoreTest.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Store\RedisStore; -use Symfony\Component\Lock\Store\RetryTillSaveStore; - -/** - * @author Jérémy Derussé - */ -class RetryTillSaveStoreTest extends AbstractStoreTest -{ - use BlockingStoreTestTrait; - - public function getStore() - { - $redis = new \Predis\Client('tcp://'.getenv('REDIS_HOST').':6379'); - try { - $redis->connect(); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - - return new RetryTillSaveStore(new RedisStore($redis), 100, 100); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php deleted file mode 100644 index b989910507818..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Store; - -use Symfony\Component\Lock\Store\SemaphoreStore; - -/** - * @author Jérémy Derussé - * - * @requires extension sysvsem - */ -class SemaphoreStoreTest extends AbstractStoreTest -{ - use BlockingStoreTestTrait; - - /** - * {@inheritdoc} - */ - protected function getStore() - { - if (PHP_VERSION_ID < 50601) { - $this->markTestSkipped('Non blocking semaphore are supported by PHP version greater or equals than 5.6.1'); - } - - return new SemaphoreStore(); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php b/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php deleted file mode 100644 index 09215f9a94d63..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php +++ /dev/null @@ -1,89 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Strategy; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Lock\Strategy\ConsensusStrategy; - -/** - * @author Jérémy Derussé - */ -class ConsensusStrategyTest extends TestCase -{ - /** @var ConsensusStrategy */ - private $strategy; - - public function setup() - { - $this->strategy = new ConsensusStrategy(); - } - - public function provideMetResults() - { - // success, failure, total, isMet - yield array(3, 0, 3, true); - yield array(2, 1, 3, true); - yield array(2, 0, 3, true); - yield array(1, 2, 3, false); - yield array(1, 1, 3, false); - yield array(1, 0, 3, false); - yield array(0, 3, 3, false); - yield array(0, 2, 3, false); - yield array(0, 1, 3, false); - yield array(0, 0, 3, false); - - yield array(2, 0, 2, true); - yield array(1, 1, 2, false); - yield array(1, 0, 2, false); - yield array(0, 2, 2, false); - yield array(0, 1, 2, false); - yield array(0, 0, 2, false); - } - - public function provideIndeterminate() - { - // success, failure, total, canBeMet - yield array(3, 0, 3, true); - yield array(2, 1, 3, true); - yield array(2, 0, 3, true); - yield array(1, 2, 3, false); - yield array(1, 1, 3, true); - yield array(1, 0, 3, true); - yield array(0, 3, 3, false); - yield array(0, 2, 3, false); - yield array(0, 1, 3, true); - yield array(0, 0, 3, true); - - yield array(2, 0, 2, true); - yield array(1, 1, 2, false); - yield array(1, 0, 2, true); - yield array(0, 2, 2, false); - yield array(0, 1, 2, false); - yield array(0, 0, 2, true); - } - - /** - * @dataProvider provideMetResults - */ - public function testMet($success, $failure, $total, $isMet) - { - $this->assertSame($isMet, $this->strategy->isMet($success, $total)); - } - - /** - * @dataProvider provideIndeterminate - */ - public function canBeMet($success, $failure, $total, $isMet) - { - $this->assertSame($isMet, $this->strategy->canBeMet($failure, $total)); - } -} diff --git a/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php b/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php deleted file mode 100644 index 76ea68a41e3b3..0000000000000 --- a/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php +++ /dev/null @@ -1,89 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Lock\Tests\Strategy; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Lock\Strategy\UnanimousStrategy; - -/** - * @author Jérémy Derussé - */ -class UnanimousStrategyTest extends TestCase -{ - /** @var UnanimousStrategy */ - private $strategy; - - public function setup() - { - $this->strategy = new UnanimousStrategy(); - } - - public function provideMetResults() - { - // success, failure, total, isMet - yield array(3, 0, 3, true); - yield array(2, 1, 3, false); - yield array(2, 0, 3, false); - yield array(1, 2, 3, false); - yield array(1, 1, 3, false); - yield array(1, 0, 3, false); - yield array(0, 3, 3, false); - yield array(0, 2, 3, false); - yield array(0, 1, 3, false); - yield array(0, 0, 3, false); - - yield array(2, 0, 2, true); - yield array(1, 1, 2, false); - yield array(1, 0, 2, false); - yield array(0, 2, 2, false); - yield array(0, 1, 2, false); - yield array(0, 0, 2, false); - } - - public function provideIndeterminate() - { - // success, failure, total, canBeMet - yield array(3, 0, 3, true); - yield array(2, 1, 3, false); - yield array(2, 0, 3, true); - yield array(1, 2, 3, false); - yield array(1, 1, 3, false); - yield array(1, 0, 3, true); - yield array(0, 3, 3, false); - yield array(0, 2, 3, false); - yield array(0, 1, 3, false); - yield array(0, 0, 3, true); - - yield array(2, 0, 2, true); - yield array(1, 1, 2, false); - yield array(1, 0, 2, true); - yield array(0, 2, 2, false); - yield array(0, 1, 2, false); - yield array(0, 0, 2, true); - } - - /** - * @dataProvider provideMetResults - */ - public function testMet($success, $failure, $total, $isMet) - { - $this->assertSame($isMet, $this->strategy->isMet($success, $total)); - } - - /** - * @dataProvider provideIndeterminate - */ - public function canBeMet($success, $failure, $total, $isMet) - { - $this->assertSame($isMet, $this->strategy->canBeMet($failure, $total)); - } -} diff --git a/src/Symfony/Component/Lock/composer.json b/src/Symfony/Component/Lock/composer.json deleted file mode 100644 index 7c25a470f90ec..0000000000000 --- a/src/Symfony/Component/Lock/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "symfony/lock", - "type": "library", - "description": "Symfony Lock Component", - "keywords": ["locking", "redlock", "mutex", "semaphore", "flock", "cas"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Jérémy Derussé", - "email": "jeremy@derusse.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=5.5.9", - "symfony/polyfill-php70": "~1.0", - "psr/log": "~1.0" - }, - "require-dev": { - "predis/predis": "~1.0" - }, - "autoload": { - "psr-4": { "Symfony\\Component\\Lock\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev" - } - } -} diff --git a/src/Symfony/Component/Lock/phpunit.xml.dist b/src/Symfony/Component/Lock/phpunit.xml.dist deleted file mode 100644 index be3ca21576fdd..0000000000000 --- a/src/Symfony/Component/Lock/phpunit.xml.dist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - ./Tests/ - - - - - - ./ - - ./Tests - ./vendor - - - - pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy