Skip to content

Commit 17fa3fc

Browse files
committed
Use _id for cache key and add @param docs
1 parent 82bc661 commit 17fa3fc

File tree

3 files changed

+62
-52
lines changed

3 files changed

+62
-52
lines changed

src/Cache/MongoLock.php

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@ final class MongoLock extends Lock
1414
/**
1515
* Create a new lock instance.
1616
*
17-
* @param Collection $collection The MongoDB collection
18-
* @param string $name
19-
* @param int $seconds
20-
* @param string|null $owner
21-
* @param array $lottery The prune probability odds
17+
* @param Collection $collection The MongoDB collection
18+
* @param string $name Name of the lock
19+
* @param int $seconds Time-to-live of the lock in seconds
20+
* @param string|null $owner A unique string that identifies the owner. Random if not set
21+
* @param array $lottery The prune probability odds
2222
* @param int $defaultTimeoutInSeconds The default number of seconds that a lock should be held
2323
*/
2424
public function __construct(
25-
private Collection $collection,
25+
private readonly Collection $collection,
2626
string $name,
2727
int $seconds,
2828
?string $owner = null,
29-
private array $lottery = [2, 100],
30-
private int $defaultTimeoutInSeconds = 86400,
29+
private readonly array $lottery = [2, 100],
30+
private readonly int $defaultTimeoutInSeconds = 86400,
3131
) {
3232
parent::__construct($name, $seconds, $owner);
3333
}
@@ -48,7 +48,7 @@ public function acquire()
4848
],
4949
];
5050
$result = $this->collection->findOneAndUpdate(
51-
['key' => ['$eq' => $this->name]],
51+
['_id' => $this->name],
5252
[
5353
[
5454
'$set' => [
@@ -82,18 +82,6 @@ public function acquire()
8282
return $result->owner === $this->owner;
8383
}
8484

85-
/**
86-
* Get the UNIX timestamp indicating when the lock should expire.
87-
*
88-
* @return int
89-
*/
90-
protected function expiresAt()
91-
{
92-
$lockTimeout = $this->seconds > 0 ? $this->seconds : $this->defaultTimeoutInSeconds;
93-
94-
return $this->currentTime() + $lockTimeout;
95-
}
96-
9785
/**
9886
* Release the lock.
9987
*
@@ -104,7 +92,7 @@ public function release()
10492
{
10593
$result = $this->collection
10694
->deleteMany([
107-
'key' => $this->name,
95+
'_id' => $this->name,
10896
'owner' => $this->owner,
10997
]);
11098

@@ -120,7 +108,7 @@ public function release()
120108
public function forceRelease(): void
121109
{
122110
$this->collection->deleteMany([
123-
'key' => $this->name,
111+
'_id' => $this->name,
124112
]);
125113
}
126114

@@ -131,8 +119,20 @@ public function forceRelease(): void
131119
protected function getCurrentOwner(): ?string
132120
{
133121
return $this->collection->findOne([
134-
'key' => $this->name,
122+
'_id' => $this->name,
135123
'expiration' => ['$gte' => $this->currentTime()],
136124
])?->owner;
137125
}
126+
127+
/**
128+
* Get the UNIX timestamp indicating when the lock should expire.
129+
*
130+
* @return int
131+
*/
132+
private function expiresAt()
133+
{
134+
$lockTimeout = $this->seconds > 0 ? $this->seconds : $this->defaultTimeoutInSeconds;
135+
136+
return $this->currentTime() + $lockTimeout;
137+
}
138138
}

src/Cache/MongoStore.php

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,23 @@ final class MongoStore implements LockProvider, Store
2626

2727
private Collection $collection;
2828

29+
/**
30+
* @param Connection $connection The MongoDB connection to use for the cache
31+
* @param string $collectionName Name of the collection where cache items are stored
32+
* @param string $prefix Prefix for the name of cache items
33+
* @param Connection|null $lockConnection The MongoDB connection to use for the lock, if different from the cache connection
34+
* @param string $lockCollectionName Name of the collection where locks are stored
35+
* @param array{int, int} $lockLottery Probability [chance, total] of pruning expired cache items
36+
* @param int $defaultLockTimeoutInSeconds Time-to-live of the locks in seconds
37+
*/
2938
public function __construct(
30-
private Connection $connection,
31-
private string $collectionName,
32-
private string $prefix = '',
33-
private ?Connection $lockConnection = null,
34-
private string $lockCollectionName = 'cache_locks',
35-
private array $lockLottery = [2, 100],
36-
private int $defaultLockTimeoutInSeconds = 86400,
39+
private readonly Connection $connection,
40+
private readonly string $collectionName = 'cache',
41+
private readonly string $prefix = '',
42+
private readonly ?Connection $lockConnection = null,
43+
private readonly string $lockCollectionName = 'cache_locks',
44+
private readonly array $lockLottery = [2, 100],
45+
private readonly int $defaultLockTimeoutInSeconds = 86400,
3746
) {
3847
$this->collection = $this->connection->getCollection($this->collectionName);
3948
}
@@ -79,7 +88,7 @@ public function put($key, $value, $seconds): bool
7988
{
8089
$result = $this->collection->updateOne(
8190
[
82-
'key' => $this->prefix . $key,
91+
'_id' => $this->prefix . $key,
8392
],
8493
[
8594
'$set' => [
@@ -107,7 +116,7 @@ public function add($key, $value, $seconds): bool
107116
{
108117
$result = $this->collection->updateOne(
109118
[
110-
'key' => $this->prefix . $key,
119+
'_id' => $this->prefix . $key,
111120
],
112121
[
113122
[
@@ -145,10 +154,14 @@ public function get($key): mixed
145154
{
146155
$result = $this->collection->findOne(
147156
[
148-
'key' => $this->prefix . $key,
157+
'_id' => $this->prefix . $key,
149158
],
150159
);
151160

161+
if (! $result) {
162+
return null;
163+
}
164+
152165
if ($result->expiration <= $this->currentTime()) {
153166
$this->forgetIfExpired($key);
154167

@@ -171,7 +184,7 @@ public function increment($key, $value = 1): int|float|false
171184

172185
$result = $this->collection->findOneAndUpdate(
173186
[
174-
'key' => $this->prefix . $key,
187+
'_id' => $this->prefix . $key,
175188
'expiration' => ['$gte' => $this->currentTime()],
176189
],
177190
[
@@ -228,7 +241,7 @@ public function forever($key, $value): bool
228241
public function forget($key): bool
229242
{
230243
$result = $this->collection->deleteOne([
231-
'key' => $this->prefix . $key,
244+
'_id' => $this->prefix . $key,
232245
]);
233246

234247
return $result->getDeletedCount() > 0;
@@ -242,7 +255,7 @@ public function forget($key): bool
242255
public function forgetIfExpired($key): bool
243256
{
244257
$result = $this->collection->deleteOne([
245-
'key' => $this->prefix . $key,
258+
'_id' => $this->prefix . $key,
246259
'expiration' => ['$lte' => $this->currentTime()],
247260
]);
248261

tests/Cache/MongoCacheStoreTest.php

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@
1414
/** Tests imported from {@see \Illuminate\Tests\Integration\Database\DatabaseCacheStoreTest} */
1515
class MongoCacheStoreTest extends TestCase
1616
{
17-
public function setUp(): void
18-
{
19-
parent::setUp();
20-
21-
DB::connection('mongodb')
22-
->getCollection($this->getCacheCollectionName())
23-
->createIndex(['key' => 1], ['unique' => true]);
24-
}
25-
2617
public function tearDown(): void
2718
{
2819
DB::connection('mongodb')
@@ -32,6 +23,12 @@ public function tearDown(): void
3223
parent::tearDown();
3324
}
3425

26+
public function testGetNullWhenItemDoesNotExist()
27+
{
28+
$store = $this->getStore();
29+
$this->assertNull($store->get('foo'));
30+
}
31+
3532
public function testValueCanStoreNewCache()
3633
{
3734
$store = $this->getStore();
@@ -47,7 +44,7 @@ public function testPutOperationShouldNotStoreExpired()
4744

4845
$store->put('foo', 'bar', 0);
4946

50-
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['key' => $this->withCachePrefix('foo')]);
47+
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['_id' => $this->withCachePrefix('foo')]);
5148
}
5249

5350
public function testValueCanUpdateExistCache()
@@ -80,7 +77,7 @@ public function testAddOperationShouldNotStoreExpired()
8077
$result = $store->add('foo', 'bar', 0);
8178

8279
$this->assertFalse($result);
83-
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['key' => $this->withCachePrefix('foo')]);
80+
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['_id' => $this->withCachePrefix('foo')]);
8481
}
8582

8683
public function testAddOperationCanStoreNewCache()
@@ -162,7 +159,7 @@ public function testGetOperationCanDeleteExpired()
162159

163160
$store->get('foo');
164161

165-
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['key' => $this->withCachePrefix('foo')]);
162+
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['_id' => $this->withCachePrefix('foo')]);
166163
}
167164

168165
public function testForgetIfExpiredOperationCanDeleteExpired()
@@ -173,7 +170,7 @@ public function testForgetIfExpiredOperationCanDeleteExpired()
173170

174171
$store->forgetIfExpired('foo');
175172

176-
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['key' => $this->withCachePrefix('foo')]);
173+
$this->assertDatabaseMissing($this->getCacheCollectionName(), ['_id' => $this->withCachePrefix('foo')]);
177174
}
178175

179176
public function testForgetIfExpiredOperationShouldNotDeleteUnExpired()
@@ -184,7 +181,7 @@ public function testForgetIfExpiredOperationShouldNotDeleteUnExpired()
184181

185182
$store->forgetIfExpired('foo');
186183

187-
$this->assertDatabaseHas($this->getCacheCollectionName(), ['key' => $this->withCachePrefix('foo')]);
184+
$this->assertDatabaseHas($this->getCacheCollectionName(), ['_id' => $this->withCachePrefix('foo')]);
188185
}
189186

190187
public function testIncrementDecrement()
@@ -225,7 +222,7 @@ protected function insertToCacheTable(string $key, $value, $ttl = 60)
225222
DB::connection('mongodb')
226223
->getCollection($this->getCacheCollectionName())
227224
->insertOne([
228-
'key' => $this->withCachePrefix($key),
225+
'_id' => $this->withCachePrefix($key),
229226
'value' => $value,
230227
'expiration' => Carbon::now()->addSeconds($ttl)->getTimestamp(),
231228
]);

0 commit comments

Comments
 (0)