Skip to content

Commit e30708d

Browse files
committed
use key state
1 parent 96f0864 commit e30708d

File tree

3 files changed

+110
-34
lines changed

3 files changed

+110
-34
lines changed

src/RoadRunnerStore.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,51 @@ final class RoadRunnerStore implements SharedLockStoreInterface
1616
{
1717
public function __construct(
1818
private readonly RrLockInterface $rrLock,
19-
private readonly string $processId
2019
) {
2120
}
2221

2322
public function save(Key $key): void
2423
{
24+
\assert(false === $key->hasState(__CLASS__));
2525
try {
26-
$lockId = $this->rrLock->lock((string)$key);
26+
$lockId = $this->rrLock->lock((string) $key);
2727
if (false === $lockId) {
2828
throw new LockConflictedException('RoadRunner. Failed to make lock');
2929
}
30+
$key->setState(__CLASS__, $lockId);
3031
} catch (RPCException $e) {
3132
throw new LockAcquiringException(message: 'RoadRunner. RPC call error', previous: $e);
3233
}
3334
}
3435

3536
public function saveRead(Key $key): void
3637
{
37-
if (false === $this->rrLock->lockRead((string)$key)) {
38+
\assert(false === $key->hasState(__CLASS__));
39+
$lockId = $this->rrLock->lockRead((string)$key);
40+
if (false === $lockId) {
3841
throw new LockConflictedException('RoadRunner. Failed to make read lock');
3942
}
43+
$key->setState(__CLASS__, $lockId);
4044
}
4145

4246
public function exists(Key $key): bool
4347
{
44-
return $this->rrLock->exists((string)$key, $this->processId);
48+
\assert($key->hasState(__CLASS__));
49+
return $this->rrLock->exists((string) $key, $key->getState(__CLASS__));
4550
}
4651

4752
public function putOffExpiration(Key $key, float $ttl): void
4853
{
49-
if (false === $this->rrLock->updateTTL((string)$key, $this->processId, $ttl)) {
54+
\assert($key->hasState(__CLASS__));
55+
if (false === $this->rrLock->updateTTL((string) $key, $key->getState(__CLASS__), $ttl)) {
5056
throw new LockConflictedException('RoadRunner. Failed to update lock ttl');
5157
}
5258
}
5359

5460
public function delete(Key $key): void
5561
{
56-
if (false === $this->rrLock->release((string)$key, $this->processId)) {
62+
\assert($key->hasState(__CLASS__));
63+
if (false === $this->rrLock->release((string) $key, $key->getState(__CLASS__))) {
5764
throw new LockReleasingException('RoadRunner. Failed to release lock');
5865
}
5966
}

tests/IntegrationTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spiral\RoadRunner\Symfony\Lock\Tests;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use RoadRunner\Lock\LockInterface as RrLock;
9+
use Spiral\RoadRunner\Symfony\Lock\RoadRunnerStore;
10+
use Symfony\Component\Lock\LockFactory;
11+
12+
final class IntegrationTest extends TestCase
13+
{
14+
public function testLock(): void
15+
{
16+
$responseList = [
17+
'test-lock' => [
18+
'uuid1',
19+
false,
20+
'uuid2'
21+
],
22+
];
23+
$rrLock = $this->createMock(RrLock::class);
24+
$rrLock
25+
->expects(self::exactly(3))
26+
->method('lock')
27+
->willReturnCallback(function (string $name) use (&$responseList) {
28+
$array_shift = \array_shift($responseList[$name]);
29+
return $array_shift;
30+
});
31+
$rrLock
32+
->expects(self::exactly(2))
33+
->method('updateTTL')
34+
->willReturn(true);
35+
36+
$rrLock
37+
->expects(self::exactly(2))
38+
->method('release')
39+
->willReturn(true);
40+
41+
// lock
42+
$factory = new LockFactory(new RoadRunnerStore($rrLock));
43+
$lock1 = $factory->createLock('test-lock');
44+
self::assertTrue($lock1->acquire());
45+
46+
$lock2 = $factory->createLock('test-lock');
47+
self::assertFalse($lock2->acquire());
48+
49+
$lock1->release();
50+
51+
// lock 2
52+
self::assertTrue($lock2->acquire());
53+
$lock2->release();
54+
}
55+
}

tests/RoadRunnerStoreTest.php

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PHPUnit\Framework\TestCase;
88
use RoadRunner\Lock\LockInterface as RrLock;
99
use Spiral\RoadRunner\Symfony\Lock\RoadRunnerStore;
10-
1110
use Symfony\Component\Lock\Exception\LockConflictedException;
1211
use Symfony\Component\Lock\Exception\LockReleasingException;
1312
use Symfony\Component\Lock\Key;
@@ -21,8 +20,11 @@ public function testSaveSuccess(): void
2120
->method('lock')
2221
->with('resource-name', null)
2322
->willReturn('lock-id');
24-
$store = new RoadRunnerStore($rrLock, 'pid');
25-
$store->save(new Key('resource-name'));
23+
$store = new RoadRunnerStore($rrLock);
24+
$key = new Key('resource-name');
25+
$store->save($key);
26+
self::assertTrue($key->hasState(RoadRunnerStore::class));
27+
self::assertSame('lock-id', $key->getState(RoadRunnerStore::class));
2628
}
2729

2830
public function testSaveReadSuccess(): void
@@ -32,41 +34,48 @@ public function testSaveReadSuccess(): void
3234
->method('lockRead')
3335
->with('resource-name', null)
3436
->willReturn('lock-id');
35-
$store = new RoadRunnerStore($rrLock, 'pid');
36-
$store->saveRead(new Key('resource-name'));
37+
$store = new RoadRunnerStore($rrLock);
38+
$key = new Key('resource-name');
39+
$store->saveRead($key);
3740
}
3841

3942
public function testExistsSuccess(): void
4043
{
4144
$rrLock = $this->createMock(RrLock::class);
4245
$rrLock->expects(self::once())
4346
->method('exists')
44-
->with('resource-name', 'pid')
47+
->with('resource-name')
4548
->willReturn(true);
46-
$store = new RoadRunnerStore($rrLock, 'pid');
47-
$store->exists(new Key('resource-name'));
49+
$store = new RoadRunnerStore($rrLock);
50+
$key = new Key('resource-name');
51+
$key->setState(RoadRunnerStore::class, 'lock-id');
52+
$store->exists($key);
4853
}
4954

5055
public function testPutOffExpirationSuccess(): void
5156
{
5257
$rrLock = $this->createMock(RrLock::class);
5358
$rrLock->expects(self::once())
5459
->method('updateTTL')
55-
->with('resource-name', 'pid', 3600.0)
60+
->with('resource-name', 'lock-id', 3600.0)
5661
->willReturn(true);
57-
$store = new RoadRunnerStore($rrLock, 'pid');
58-
$store->putOffExpiration(new Key('resource-name'), 3600.0);
62+
$store = new RoadRunnerStore($rrLock);
63+
$key = new Key('resource-name');
64+
$key->setState(RoadRunnerStore::class, 'lock-id');
65+
$store->putOffExpiration($key, 3600.0);
5966
}
6067

6168
public function testDeleteSuccess(): void
6269
{
6370
$rrLock = $this->createMock(RrLock::class);
6471
$rrLock->expects(self::once())
6572
->method('release')
66-
->with('resource-name', 'pid')
73+
->with('resource-name')
6774
->willReturn(true);
68-
$store = new RoadRunnerStore($rrLock, 'pid');
69-
$store->delete(new Key('resource-name'));
75+
$store = new RoadRunnerStore($rrLock);
76+
$key = new Key('resource-name');
77+
$key->setState(RoadRunnerStore::class, 'lock-id');
78+
$store->delete($key);
7079
}
7180

7281
public function testSaveFail(): void
@@ -79,7 +88,7 @@ public function testSaveFail(): void
7988
->method('lock')
8089
->with('resource-name', null)
8190
->willReturn(false);
82-
$store = new RoadRunnerStore($rrLock, 'pid');
91+
$store = new RoadRunnerStore($rrLock);
8392
$store->save(new Key('resource-name'));
8493
}
8594

@@ -92,21 +101,22 @@ public function testSaveReadFail(): void
92101
$rrLock->expects(self::once())
93102
->method('lockRead')
94103
->with('resource-name', null);
95-
$store = new RoadRunnerStore($rrLock, 'pid');
96-
$store->saveRead(new Key('resource-name'));
104+
$store = new RoadRunnerStore($rrLock);
105+
$key = new Key('resource-name');
106+
$store->saveRead($key);
97107
}
98108

99109
public function testExistsFail(): void
100110
{
101111
$rrLock = $this->createMock(RrLock::class);
102112
$rrLock->expects(self::once())
103113
->method('exists')
104-
->with('resource-name', 'pid')
114+
->with('resource-name')
105115
->willReturn(false);
106-
$store = new RoadRunnerStore($rrLock, 'pid');
107-
self::assertFalse(
108-
$store->exists(new Key('resource-name'))
109-
);
116+
$store = new RoadRunnerStore($rrLock);
117+
$key = new Key('resource-name');
118+
$key->setState(RoadRunnerStore::class, 'lock-id');
119+
self::assertFalse($store->exists($key));
110120
}
111121

112122
public function testPutOffExpirationFail(): void
@@ -117,10 +127,12 @@ public function testPutOffExpirationFail(): void
117127
$rrLock = $this->createMock(RrLock::class);
118128
$rrLock->expects(self::once())
119129
->method('updateTTL')
120-
->with('resource-name', 'pid', 3600.0)
130+
->with('resource-name', 'lock-id', 3600.0)
121131
->willReturn(false);
122-
$store = new RoadRunnerStore($rrLock, 'pid');
123-
$store->putOffExpiration(new Key('resource-name'), 3600.0);
132+
$store = new RoadRunnerStore($rrLock);
133+
$key = new Key('resource-name');
134+
$key->setState(RoadRunnerStore::class, 'lock-id');
135+
$store->putOffExpiration($key, 3600.0);
124136
}
125137

126138
public function testDeleteFail(): void
@@ -131,9 +143,11 @@ public function testDeleteFail(): void
131143
$rrLock = $this->createMock(RrLock::class);
132144
$rrLock->expects(self::once())
133145
->method('release')
134-
->with('resource-name', 'pid')
146+
->with('resource-name')
135147
->willReturn(false);
136-
$store = new RoadRunnerStore($rrLock, 'pid');
137-
$store->delete(new Key('resource-name'));
148+
$store = new RoadRunnerStore($rrLock);
149+
$key = new Key('resource-name');
150+
$key->setState(RoadRunnerStore::class, 'lock-id');
151+
$store->delete($key);
138152
}
139153
}

0 commit comments

Comments
 (0)