Skip to content

Commit 3efcaa2

Browse files
Create new NotExpirableStoreException for stores that don't support expiration of locks.
1 parent 97c8fac commit 3efcaa2

12 files changed

+82
-4
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Exception;
13+
14+
/**
15+
* NotExpirableStoreException is thrown when a store doesn't support expiration of locks.
16+
*
17+
* @author Ganesh Chandrasekaran <gchandrasekaran@wayfair.com>
18+
*/
19+
class NotExpirableStoreException extends \LogicException implements ExceptionInterface
20+
{
21+
}

src/Symfony/Component/Lock/Lock.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Lock\Exception\LockConflictedException;
2020
use Symfony\Component\Lock\Exception\LockExpiredException;
2121
use Symfony\Component\Lock\Exception\LockReleasingException;
22+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
2223

2324
/**
2425
* Lock is the default implementation of the LockInterface.
@@ -124,6 +125,8 @@ public function refresh($ttl = null)
124125
}
125126

126127
$this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $ttl));
128+
} catch (NotExpirableStoreException $e) {
129+
$this->logger->notice('The store does not support expiration of locks.', array('store' => $this->store));
127130
} catch (LockConflictedException $e) {
128131
$this->dirty = false;
129132
$this->logger->notice('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock.', array('resource' => $this->key));

src/Symfony/Component/Lock/Store/CombinedStore.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Lock\Exception\InvalidArgumentException;
1818
use Symfony\Component\Lock\Exception\LockConflictedException;
1919
use Symfony\Component\Lock\Exception\LockExpiredException;
20+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
2021
use Symfony\Component\Lock\Exception\NotSupportedException;
2122
use Symfony\Component\Lock\Key;
2223
use Symfony\Component\Lock\StoreInterface;
@@ -115,6 +116,9 @@ public function putOffExpiration(Key $key, $ttl)
115116

116117
$store->putOffExpiration($key, $adjustedTtl);
117118
++$successCount;
119+
} catch (NotExpirableStoreException $e) {
120+
$this->logger->notice('The store does not support expiration of locks.', array('store' => $store));
121+
++$successCount;
118122
} catch (\Exception $e) {
119123
$this->logger->warning('One store failed to put off the expiration of the "{resource}" lock.', array('resource' => $key, 'store' => $store, 'exception' => $e));
120124
++$failureCount;

src/Symfony/Component/Lock/Store/FlockStore.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Lock\Exception\InvalidArgumentException;
1515
use Symfony\Component\Lock\Exception\LockConflictedException;
1616
use Symfony\Component\Lock\Exception\LockStorageException;
17+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
1718
use Symfony\Component\Lock\Key;
1819
use Symfony\Component\Lock\StoreInterface;
1920

@@ -108,7 +109,7 @@ private function lock(Key $key, $blocking)
108109
*/
109110
public function putOffExpiration(Key $key, $ttl)
110111
{
111-
// do nothing, the flock locks forever.
112+
throw new NotExpirableStoreException();
112113
}
113114

114115
/**

src/Symfony/Component/Lock/Store/SemaphoreStore.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Lock\Exception\InvalidArgumentException;
1515
use Symfony\Component\Lock\Exception\LockConflictedException;
16+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
1617
use Symfony\Component\Lock\Key;
1718
use Symfony\Component\Lock\StoreInterface;
1819

@@ -102,7 +103,7 @@ public function delete(Key $key)
102103
*/
103104
public function putOffExpiration(Key $key, $ttl)
104105
{
105-
// do nothing, the semaphore locks forever.
106+
throw new NotExpirableStoreException();
106107
}
107108

108109
/**

src/Symfony/Component/Lock/Store/ZookeeperStore.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Lock\Exception\LockAcquiringException;
1515
use Symfony\Component\Lock\Exception\LockConflictedException;
1616
use Symfony\Component\Lock\Exception\LockReleasingException;
17+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
1718
use Symfony\Component\Lock\Exception\NotSupportedException;
1819
use Symfony\Component\Lock\Key;
1920
use Symfony\Component\Lock\StoreInterface;
@@ -91,7 +92,7 @@ public function waitAndSave(Key $key)
9192
*/
9293
public function putOffExpiration(Key $key, $ttl)
9394
{
94-
throw new NotSupportedException();
95+
throw new NotExpirableStoreException();
9596
}
9697

9798
/**

src/Symfony/Component/Lock/StoreInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Lock\Exception\LockAcquiringException;
1515
use Symfony\Component\Lock\Exception\LockConflictedException;
1616
use Symfony\Component\Lock\Exception\LockReleasingException;
17+
use Symfony\Component\Lock\Exception\NotExpirableStoreException;
1718
use Symfony\Component\Lock\Exception\NotSupportedException;
1819

1920
/**
@@ -49,6 +50,7 @@ public function waitAndSave(Key $key);
4950
* @param float $ttl amount of second to keep the lock in the store
5051
*
5152
* @throws LockConflictedException
53+
* @throws NotExpirableStoreException
5254
* @throws NotSupportedException
5355
*/
5456
public function putOffExpiration(Key $key, $ttl);

src/Symfony/Component/Lock/Tests/Store/CombinedStoreTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Lock\Key;
1616
use Symfony\Component\Lock\Store\CombinedStore;
1717
use Symfony\Component\Lock\Store\RedisStore;
18+
use Symfony\Component\Lock\Store\ZookeeperStore;
1819
use Symfony\Component\Lock\StoreInterface;
1920
use Symfony\Component\Lock\Strategy\StrategyInterface;
2021
use Symfony\Component\Lock\Strategy\UnanimousStrategy;
@@ -46,7 +47,10 @@ public function getStore()
4647
self::markTestSkipped($e->getMessage());
4748
}
4849

49-
return new CombinedStore(array(new RedisStore($redis)), new UnanimousStrategy());
50+
$zookeeper_server = getenv('ZOOKEEPER_HOST').':2181';
51+
$zookeeper = new \Zookeeper(implode(',', array($zookeeper_server)));
52+
53+
return new CombinedStore(array(new RedisStore($redis), new ZookeeperStore($zookeeper)), new UnanimousStrategy());
5054
}
5155

5256
/** @var \PHPUnit_Framework_MockObject_MockObject */

src/Symfony/Component/Lock/Tests/Store/FlockStoreTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
class FlockStoreTest extends AbstractStoreTest
2121
{
2222
use BlockingStoreTestTrait;
23+
use NotExpiringStoreTestTrait;
2324

2425
/**
2526
* {@inheritdoc}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock\Tests\Store;
13+
14+
use Symfony\Component\Lock\Key;
15+
16+
/**
17+
* @author Ganesh Chandrasekaran <gchandrasekaran@wayfair.com>
18+
*/
19+
trait NotExpiringStoreTestTrait
20+
{
21+
/**
22+
* @see AbstractStoreTest::getStore()
23+
*/
24+
abstract protected function getStore();
25+
26+
/**
27+
* @expectedException \Symfony\Component\Lock\Exception\NotExpirableStoreException
28+
*/
29+
public function testPutOffExpirationThrowsException()
30+
{
31+
$store = $this->getStore();
32+
$key = new Key(uniqid(__METHOD__, true));
33+
34+
$store->save($key);
35+
$store->putOffExpiration($key, 10.0);
36+
}
37+
}

src/Symfony/Component/Lock/Tests/Store/SemaphoreStoreTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
class SemaphoreStoreTest extends AbstractStoreTest
2323
{
2424
use BlockingStoreTestTrait;
25+
use NotExpiringStoreTestTrait;
2526

2627
/**
2728
* {@inheritdoc}

src/Symfony/Component/Lock/Tests/Store/ZookeeperStoreTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
class ZookeeperStoreTest extends AbstractStoreTest
2424
{
25+
use NotExpiringStoreTestTrait;
26+
2527
public function getStore(): ZookeeperStore
2628
{
2729
$zookeeper_server = getenv('ZOOKEEPER_HOST').':2181';

0 commit comments

Comments
 (0)