diff --git a/CHANGELOG.md b/CHANGELOG.md index efdc633..51f71ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.1.0 +### Changed +- Renamed existing `ttl` parameter to `ttw` for lock time to wait +- Added new `ttl` parameter for lock time to live + ## 2.0.0 ### Removed - Symfony 2.* support diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index e1fc7af..bd42cff 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -17,7 +17,8 @@ public function getConfigTreeBuilder() $rootNode ->children() - ->scalarNode('ttl')->defaultValue(5)->end() + ->scalarNode('ttw')->defaultValue(5)->end() + ->scalarNode('ttl')->defaultNull()->end() ->scalarNode('redis_client')->isRequired()->cannotBeEmpty()->end() ->end() ; diff --git a/src/DependencyInjection/PayseraLockExtension.php b/src/DependencyInjection/PayseraLockExtension.php index 0211b71..ab37747 100644 --- a/src/DependencyInjection/PayseraLockExtension.php +++ b/src/DependencyInjection/PayseraLockExtension.php @@ -15,7 +15,8 @@ public function load(array $configs, ContainerBuilder $container) $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $container->setParameter('paysera_lock.ttl', (int) $config['ttl']); + $container->setParameter('paysera_lock.ttw', $config['ttw']); + $container->setParameter('paysera_lock.ttl', $config['ttl']); $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.xml'); diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 8f531d8..2910770 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -17,6 +17,7 @@ + %paysera_lock.ttw% %paysera_lock.ttl% diff --git a/src/Service/LockManager.php b/src/Service/LockManager.php index 4744975..95a6c9a 100644 --- a/src/Service/LockManager.php +++ b/src/Service/LockManager.php @@ -11,29 +11,32 @@ class LockManager { private $lockFactory; + private $ttw; private $ttl; public function __construct( Factory $lockFactory, - int $ttl + int $ttw, + int $ttl = null ) { $this->lockFactory = $lockFactory; + $this->ttw = $ttw; $this->ttl = $ttl; } public function createLock(string $resource): LockInterface { - return $this->lockFactory->createLock($resource, null); + return $this->lockFactory->createLock($resource, $this->ttl); } public function acquire(LockInterface $lock): bool { - foreach (range(1, $this->ttl) as $waited) { + foreach (range(1, $this->ttw) as $waited) { if ($lock->acquire()) { return true; } - if ($waited >= $this->ttl) { + if ($waited >= $this->ttw) { throw new LockAcquiringException('Failed to acquire lock, wait time expired'); } diff --git a/test/BundleTest.php b/test/BundleTest.php index f9fd8b2..2447dd7 100644 --- a/test/BundleTest.php +++ b/test/BundleTest.php @@ -34,8 +34,11 @@ protected function tearDown() public function testLockManagerConfiguration() { + $ttw = $this->container->getParameter('paysera_lock.ttw'); + $this->assertEquals(10, $ttw); + $ttl = $this->container->getParameter('paysera_lock.ttl'); - $this->assertEquals(10, $ttl); + $this->assertNull($ttl); $lockManager = $this->container->get('paysera_lock.lock_manager'); $this->assertInstanceOf(LockManager::class, $lockManager); diff --git a/test/Service/LockManagerTest.php b/test/Service/LockManagerTest.php new file mode 100644 index 0000000..13cfe4f --- /dev/null +++ b/test/Service/LockManagerTest.php @@ -0,0 +1,108 @@ +lockFactory = $this->createMock(Factory::class); + $this->lockManager = new LockManager( + $this->lockFactory, + 2, + 1 + ); + } + + public function testCreateLock() + { + $lock = $this->createMock(LockInterface::class); + $this->lockFactory + ->expects($this->once()) + ->method('createLock') + ->with('resource', 1) + ->willReturn($lock) + ; + + $createdLock = $this->lockManager->createLock('resource'); + + $this->assertEquals($lock, $createdLock); + } + + public function testAcquire() + { + $lock = $this->createMock(LockInterface::class); + $lock + ->expects($this->exactly(2)) + ->method('acquire') + ->willReturnOnConsecutiveCalls(false, true) + ; + + $this->lockManager->acquire($lock); + } + + public function testAcquireTtw() + { + $lock = $this->createMock(LockInterface::class); + $lock + ->expects($this->exactly(2)) + ->method('acquire') + ->willReturnOnConsecutiveCalls(false, false) + ; + + $this->expectException(LockAcquiringException::class); + $this->expectExceptionMessage('Failed to acquire lock, wait time expired'); + + $this->lockManager->acquire($lock); + } + + public function testCreateAcquired() + { + $lock = $this->createMock(LockInterface::class); + $lock + ->expects($this->once()) + ->method('acquire') + ->willReturn(true) + ; + + $this->lockFactory + ->expects($this->once()) + ->method('createLock') + ->with('resource', 1) + ->willReturn($lock) + ; + + $created = $this->lockManager->createAcquired('resource'); + + $this->assertEquals($lock, $created); + } + + public function testRelease() + { + $lock = $this->createMock(LockInterface::class); + $lock + ->expects($this->once()) + ->method('release') + ; + $this->lockManager->release($lock); + } +} diff --git a/test/config.yml b/test/config.yml index a98817c..6a47916 100644 --- a/test/config.yml +++ b/test/config.yml @@ -11,5 +11,5 @@ snc_redis: dsn: redis://localhost paysera_lock: - ttl: 10 + ttw: 10 redis_client: 'snc_redis.default'