From b985ca2dcf5a7ebfa68dbfc947b4d2813100d178 Mon Sep 17 00:00:00 2001 From: Maksym Khrystunov Date: Wed, 2 Aug 2023 10:56:56 +0300 Subject: [PATCH 1/3] Use separate ttl and ttw in LockManager --- src/DependencyInjection/Configuration.php | 3 +- .../PayseraLockExtension.php | 3 +- src/Resources/config/services.xml | 3 +- src/Service/LockManager.php | 14 ++- test/BundleTest.php | 5 +- test/Service/LockManagerTest.php | 108 ++++++++++++++++++ test/config.yml | 2 +- 7 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 test/Service/LockManagerTest.php 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..4a05416 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -10,13 +10,14 @@ + class="Symfony\Component\Lock\LockFactory"> + %paysera_lock.ttw% %paysera_lock.ttl% diff --git a/src/Service/LockManager.php b/src/Service/LockManager.php index 4744975..ab8fc54 100644 --- a/src/Service/LockManager.php +++ b/src/Service/LockManager.php @@ -6,34 +6,38 @@ use Symfony\Component\Lock\Exception\LockAcquiringException; use Symfony\Component\Lock\Factory; +use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockInterface; class LockManager { private $lockFactory; + private $ttw; private $ttl; public function __construct( - Factory $lockFactory, - int $ttl + LockFactory $lockFactory, + 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..a48e19c --- /dev/null +++ b/test/Service/LockManagerTest.php @@ -0,0 +1,108 @@ +lockFactory = $this->createMock(LockFactory::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' From 1b46520eb5db23bb93e0aba4fc7e8b25ecc44d23 Mon Sep 17 00:00:00 2001 From: Maksym Khrystunov Date: Fri, 4 Aug 2023 11:56:30 +0300 Subject: [PATCH 2/3] SUPPORT-77360: Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efdc633..f3ff9ad 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.0.1 +### 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 From 10191cb972caec5a6a88783bede897cc246d531e Mon Sep 17 00:00:00 2001 From: Maksym Khrystunov Date: Fri, 4 Aug 2023 13:39:50 +0300 Subject: [PATCH 3/3] SUPPORT-77360: bump minor in CHANGELOG; revert LockFactory -> Factory --- CHANGELOG.md | 2 +- src/Resources/config/services.xml | 2 +- src/Service/LockManager.php | 3 +-- test/Service/LockManagerTest.php | 6 +++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3ff9ad..51f71ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 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.0.1 +## 2.1.0 ### Changed - Renamed existing `ttl` parameter to `ttw` for lock time to wait - Added new `ttl` parameter for lock time to live diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 4a05416..2910770 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -10,7 +10,7 @@ + class="Symfony\Component\Lock\Factory"> diff --git a/src/Service/LockManager.php b/src/Service/LockManager.php index ab8fc54..95a6c9a 100644 --- a/src/Service/LockManager.php +++ b/src/Service/LockManager.php @@ -6,7 +6,6 @@ use Symfony\Component\Lock\Exception\LockAcquiringException; use Symfony\Component\Lock\Factory; -use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockInterface; class LockManager @@ -16,7 +15,7 @@ class LockManager private $ttl; public function __construct( - LockFactory $lockFactory, + Factory $lockFactory, int $ttw, int $ttl = null ) { diff --git a/test/Service/LockManagerTest.php b/test/Service/LockManagerTest.php index a48e19c..13cfe4f 100644 --- a/test/Service/LockManagerTest.php +++ b/test/Service/LockManagerTest.php @@ -8,7 +8,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Lock\Exception\LockAcquiringException; -use Symfony\Component\Lock\LockFactory; +use Symfony\Component\Lock\Factory; use Symfony\Component\Lock\LockInterface; class LockManagerTest extends TestCase @@ -19,13 +19,13 @@ class LockManagerTest extends TestCase private $lockManager; /** - * @var MockObject|LockFactory + * @var MockObject|Factory */ private $lockFactory; public function setUp() { - $this->lockFactory = $this->createMock(LockFactory::class); + $this->lockFactory = $this->createMock(Factory::class); $this->lockManager = new LockManager( $this->lockFactory, 2,