From de412bf24b23a04b25136c37e756bbd69fc1acb2 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 14 Oct 2020 08:54:02 +0200 Subject: [PATCH] Reset lifetime on acquireRead() --- src/Symfony/Component/Lock/Lock.php | 1 + src/Symfony/Component/Lock/Tests/LockTest.php | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/Symfony/Component/Lock/Lock.php b/src/Symfony/Component/Lock/Lock.php index 0788138016..ccb0184c18 100644 --- a/src/Symfony/Component/Lock/Lock.php +++ b/src/Symfony/Component/Lock/Lock.php @@ -121,6 +121,7 @@ final class Lock implements SharedLockInterface, LoggerAwareInterface */ public function acquireRead(bool $blocking = false): bool { + $this->key->resetLifetime(); try { if (!$this->store instanceof SharedLockStoreInterface) { $this->logger->debug('Store does not support ReadLocks, fallback to WriteLock.', ['resource' => $this->key]); diff --git a/src/Symfony/Component/Lock/Tests/LockTest.php b/src/Symfony/Component/Lock/Tests/LockTest.php index cc8b96f561..fb83293637 100644 --- a/src/Symfony/Component/Lock/Tests/LockTest.php +++ b/src/Symfony/Component/Lock/Tests/LockTest.php @@ -20,6 +20,7 @@ use Symfony\Component\Lock\Key; use Symfony\Component\Lock\Lock; use Symfony\Component\Lock\PersistingStoreInterface; use Symfony\Component\Lock\SharedLockStoreInterface; +use Symfony\Component\Lock\Store\ExpiringStoreTrait; /** * @author Jérémy Derussé @@ -429,6 +430,52 @@ class LockTest extends TestCase $this->assertTrue($lock->acquireRead(false)); } + /** + * @group time-sensitive + */ + public function testAcquireReadTwiceWithExpiration() + { + $key = new Key(uniqid(__METHOD__, true)); + $store = new class() implements PersistingStoreInterface { + use ExpiringStoreTrait; + private $keys = []; + private $initialTtl = 30; + + public function save(Key $key) + { + $key->reduceLifetime($this->initialTtl); + $this->keys[spl_object_hash($key)] = $key; + $this->checkNotExpired($key); + + return true; + } + + public function delete(Key $key) + { + unset($this->keys[spl_object_hash($key)]); + } + + public function exists(Key $key) + { + return isset($this->keys[spl_object_hash($key)]); + } + + public function putOffExpiration(Key $key, float $ttl) + { + $key->reduceLifetime($ttl); + $this->checkNotExpired($key); + } + }; + $ttl = 1; + $lock = new Lock($key, $store, $ttl); + + $this->assertTrue($lock->acquireRead()); + $lock->release(); + sleep($ttl + 1); + $this->assertTrue($lock->acquireRead()); + $lock->release(); + } + public function testAcquireReadBlockingWithBlockingSharedLockStoreInterface() { $key = new Key(uniqid(__METHOD__, true));