Skip to content

Commit 70a01ac

Browse files
committed
Configurable autorelease
1 parent 14ebf6a commit 70a01ac

File tree

3 files changed

+37
-16
lines changed

3 files changed

+37
-16
lines changed

src/Symfony/Component/Lock/Factory.php

+5-4
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ public function __construct(StoreInterface $store)
3636
/**
3737
* Creates a lock for the given resource.
3838
*
39-
* @param string $resource The resource to lock
40-
* @param float $ttl Maximum expected lock duration in seconds
39+
* @param string $resource The resource to lock
40+
* @param float $ttl Maximum expected lock duration in seconds
41+
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
4142
*
4243
* @return Lock
4344
*/
44-
public function createLock($resource, $ttl = 300.0)
45+
public function createLock($resource, $ttl = 300.0, $autoRelease = true)
4546
{
46-
$lock = new Lock(new Key($resource), $this->store, $ttl);
47+
$lock = new Lock(new Key($resource), $this->store, $ttl, $autoRelease);
4748
$lock->setLogger($this->logger);
4849

4950
return $lock;

src/Symfony/Component/Lock/Lock.php

+12-11
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,35 @@ final class Lock implements LockInterface, LoggerAwareInterface
3232
private $store;
3333
private $key;
3434
private $ttl;
35+
private $autoRelease;
3536
private $dirty = false;
3637

3738
/**
38-
* @param Key $key Resource to lock
39-
* @param StoreInterface $store Store used to handle lock persistence
40-
* @param float|null $ttl Maximum expected lock duration in seconds
39+
* @param Key $key Resource to lock
40+
* @param StoreInterface $store Store used to handle lock persistence
41+
* @param float|null $ttl Maximum expected lock duration in seconds
42+
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
4143
*/
42-
public function __construct(Key $key, StoreInterface $store, $ttl = null)
44+
public function __construct(Key $key, StoreInterface $store, $ttl = null, $autoRelease = true)
4345
{
4446
$this->store = $store;
4547
$this->key = $key;
4648
$this->ttl = $ttl;
49+
$this->autoRelease = (bool) $autoRelease;
4750

4851
$this->logger = new NullLogger();
4952
}
5053

5154
/**
52-
* Automatically release the underlying lock when the object is destructed.
55+
* Automatically releases the underlying lock when the object is destructed.
5356
*/
5457
public function __destruct()
5558
{
56-
try {
57-
if ($this->dirty && $this->isAcquired()) {
58-
$this->release();
59-
}
60-
} catch (\Throwable $e) {
61-
} catch (\Exception $e) {
59+
if (!$this->autoRelease || !$this->dirty || !$this->isAcquired()) {
60+
return;
6261
}
62+
63+
$this->release();
6364
}
6465

6566
/**

src/Symfony/Component/Lock/Tests/LockTest.php

+20-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function testIsAquired()
106106
->expects($this->any())
107107
->method('exists')
108108
->with($key)
109-
->willReturn(true);
109+
->will($this->onConsecutiveCalls(true, false));
110110

111111
$this->assertTrue($lock->isAcquired());
112112
}
@@ -150,6 +150,25 @@ public function testReleaseOnDestruction()
150150
unset($lock);
151151
}
152152

153+
public function testNoAutoReleaseWhenNotConfigured()
154+
{
155+
$key = new Key(uniqid(__METHOD__, true));
156+
$store = $this->getMockBuilder(StoreInterface::class)->getMock();
157+
$lock = new Lock($key, $store, 10, false);
158+
159+
$store
160+
->method('exists')
161+
->willReturnOnConsecutiveCalls(array(true, false))
162+
;
163+
$store
164+
->expects($this->never())
165+
->method('delete')
166+
;
167+
168+
$lock->acquire(false);
169+
unset($lock);
170+
}
171+
153172
/**
154173
* @expectedException \Symfony\Component\Lock\Exception\LockReleasingException
155174
*/

0 commit comments

Comments
 (0)