Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 09c696f

Browse filesBrowse files
committed
Expose an expiringDate and isExpired method in Lock
1 parent b118226 commit 09c696f
Copy full SHA for 09c696f

File tree

6 files changed

+90
-4
lines changed
Filter options

6 files changed

+90
-4
lines changed

‎src/Symfony/Component/Lock/Key.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Key.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
final class Key
2020
{
2121
private $resource;
22+
private $expiringDate;
2223
private $state = array();
2324

2425
/**
@@ -70,4 +71,27 @@ public function getState($stateKey)
7071
{
7172
return $this->state[$stateKey];
7273
}
74+
75+
public function resetExpiringDate()
76+
{
77+
$this->expiringDate = null;
78+
}
79+
80+
/**
81+
* @param \DateTimeImmutable $expiringDate
82+
*/
83+
public function reduceExpiringDate(\DateTimeImmutable $expiringDate)
84+
{
85+
if (null === $this->expiringDate || $this->expiringDate > $expiringDate) {
86+
$this->expiringDate = $expiringDate;
87+
}
88+
}
89+
90+
/**
91+
* @return \DateTimeImmutable
92+
*/
93+
public function getExpiringDate()
94+
{
95+
return $this->expiringDate;
96+
}
7397
}

‎src/Symfony/Component/Lock/Lock.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Lock.php
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public function refresh()
8989
}
9090

9191
try {
92+
$this->key->resetExpiringDate();
9293
$this->store->putOffExpiration($this->key, $this->ttl);
9394
$this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $this->ttl));
9495
} catch (LockConflictedException $e) {
@@ -120,4 +121,21 @@ public function release()
120121
throw new LockReleasingException(sprintf('Failed to release the "%s" lock.', $this->key));
121122
}
122123
}
124+
125+
/**
126+
* @return bool
127+
*/
128+
public function isExpired()
129+
{
130+
if (null === $expireDate = $this->key->getExpiringDate()) {
131+
return false;
132+
}
133+
134+
return $expireDate <= new \DateTime();
135+
}
136+
137+
public function getExpiringDate()
138+
{
139+
return $this->key->getExpiringDate();
140+
}
123141
}

‎src/Symfony/Component/Lock/Store/MemcachedStore.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Store/MemcachedStore.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function save(Key $key)
5858
{
5959
$token = $this->getToken($key);
6060

61+
$key->reduceExpiringDate(\DateTimeImmutable::createFromFormat('U.u', (string) microtime(true) + $this->initialTtl));
6162
if ($this->memcached->add((string) $key, $token, (int) ceil($this->initialTtl))) {
6263
return;
6364
}
@@ -87,6 +88,7 @@ public function putOffExpiration(Key $key, $ttl)
8788

8889
list($value, $cas) = $this->getValueAndCas($key);
8990

91+
$key->reduceExpiringDate(\DateTimeImmutable::createFromFormat('U.u', (string) microtime(true) + $ttl));
9092
// Could happens when we ask a putOff after a timeout but in luck nobody steal the lock
9193
if (\Memcached::RES_NOTFOUND === $this->memcached->getResultCode()) {
9294
if ($this->memcached->add((string) $key, $token, $ttl)) {

‎src/Symfony/Component/Lock/Store/RedisStore.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Store/RedisStore.php
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ public function save(Key $key)
5757
end
5858
';
5959

60-
$expire = (int) ceil($this->initialTtl * 1000);
61-
if (!$this->evaluate($script, (string) $key, array($this->getToken($key), $expire))) {
60+
$key->reduceExpiringDate(\DateTimeImmutable::createFromFormat('U.u', (string) microtime(true) + $this->initialTtl));
61+
if (!$this->evaluate($script, (string) $key, array($this->getToken($key), (int) ceil($this->initialTtl * 1000)))) {
6262
throw new LockConflictedException();
6363
}
6464
}
@@ -81,8 +81,8 @@ public function putOffExpiration(Key $key, $ttl)
8181
end
8282
';
8383

84-
$expire = (int) ceil($ttl * 1000);
85-
if (!$this->evaluate($script, (string) $key, array($this->getToken($key), $expire))) {
84+
$key->reduceExpiringDate(\DateTimeImmutable::createFromFormat('U.u', (string) microtime(true) + $ttl));
85+
if (!$this->evaluate($script, (string) $key, array($this->getToken($key), (int) ceil($ttl * 1000)))) {
8686
throw new LockConflictedException();
8787
}
8888
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Tests/LockTest.php
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,34 @@ public function testReleaseThrowsExceptionIfNotWellDeleted()
153153

154154
$lock->release();
155155
}
156+
157+
/**
158+
* @dataProvider provideExpiredDates
159+
*/
160+
public function testExpiration($dates, $expected)
161+
{
162+
$key = new Key(uniqid(__METHOD__, true));
163+
$store = $this->getMockBuilder(StoreInterface::class)->getMock();
164+
$lock = new Lock($key, $store, 10);
165+
166+
foreach ($dates as $date) {
167+
if (null === $date) {
168+
$key->resetExpiringDate();
169+
} else {
170+
$key->reduceExpiringDate(new \DateTimeImmutable($date));
171+
}
172+
}
173+
$this->assertSame($expected, $lock->isExpired());
174+
}
175+
176+
public function provideExpiredDates()
177+
{
178+
yield array(array('yesterday'), true);
179+
yield array(array('tomorrow', 'yesterday'), true);
180+
yield array(array('yesterday', 'tomorrow'), true);
181+
182+
yield array(array(), false);
183+
yield array(array('tomorrow'), false);
184+
yield array(array('yesterday', null), false);
185+
}
156186
}

‎src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Tests/Store/ExpiringStoreTestTrait.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,16 @@ public function testRefreshLock()
7575
usleep(2.1 * $clockDelay);
7676
$this->assertFalse($store->exists($key));
7777
}
78+
79+
public function testSetExpiration()
80+
{
81+
$key = new Key(uniqid(__METHOD__, true));
82+
83+
/** @var StoreInterface $store */
84+
$store = $this->getStore();
85+
86+
$store->save($key);
87+
$store->putOffExpiration($key, 1);
88+
$this->assertNotNull($key->getExpiringDate());
89+
}
7890
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.