Skip to content

Commit 14c49a7

Browse files
[12.x] Add flexible support to memoized cache store (#55709)
* Add flexible support to memoized cache store * Update MemoizedStore.php * Update MemoizedStore.php --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent 28704dd commit 14c49a7

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

src/Illuminate/Cache/MemoizedStore.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace Illuminate\Cache;
44

5+
use BadMethodCallException;
6+
use Illuminate\Contracts\Cache\LockProvider;
57
use Illuminate\Contracts\Cache\Store;
68

7-
class MemoizedStore implements Store
9+
class MemoizedStore implements LockProvider, Store
810
{
911
/**
1012
* The memoized cache values.
@@ -160,6 +162,39 @@ public function forever($key, $value)
160162
return $this->repository->forever($key, $value);
161163
}
162164

165+
/**
166+
* Get a lock instance.
167+
*
168+
* @param string $name
169+
* @param int $seconds
170+
* @param string|null $owner
171+
* @return \Illuminate\Contracts\Cache\Lock
172+
*/
173+
public function lock($name, $seconds = 0, $owner = null)
174+
{
175+
if (! $this->repository->getStore() instanceof LockProvider) {
176+
throw new BadMethodCallException('This cache store does not support locks.');
177+
}
178+
179+
return $this->repository->getStore()->lock(...func_get_args());
180+
}
181+
182+
/**
183+
* Restore a lock instance using the owner identifier.
184+
*
185+
* @param string $name
186+
* @param string $owner
187+
* @return \Illuminate\Contracts\Cache\Lock
188+
*/
189+
public function restoreLock($name, $owner)
190+
{
191+
if (! $this->repository instanceof LockProvider) {
192+
throw new BadMethodCallException('This cache store does not support locks.');
193+
}
194+
195+
return $this->repository->resoreLock(...func_get_args());
196+
}
197+
163198
/**
164199
* Remove an item from the cache.
165200
*

tests/Integration/Cache/MemoizedStoreTest.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Illuminate\Tests\Integration\Cache;
44

5+
use BadMethodCallException;
56
use Illuminate\Cache\Events\CacheEvent;
67
use Illuminate\Cache\Events\CacheMissed;
78
use Illuminate\Cache\Events\ForgettingKey;
@@ -10,12 +11,16 @@
1011
use Illuminate\Cache\Events\RetrievingKey;
1112
use Illuminate\Cache\Events\RetrievingManyKeys;
1213
use Illuminate\Cache\Events\WritingKey;
14+
use Illuminate\Contracts\Cache\Store;
1315
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
1416
use Illuminate\Support\Facades\Cache;
1517
use Illuminate\Support\Facades\Config;
1618
use Illuminate\Support\Facades\Event;
19+
use Illuminate\Support\Facades\Exceptions;
1720
use Illuminate\Support\Facades\Redis;
21+
use Illuminate\Support\Facades\Route;
1822
use Orchestra\Testbench\TestCase;
23+
use Throwable;
1924

2025
class MemoizedStoreTest extends TestCase
2126
{
@@ -406,4 +411,84 @@ public function test_it_resets_cache_store_with_scoped_instances()
406411
$this->assertSame('Taylor', $live);
407412
$this->assertSame('Taylor', $memoized);
408413
}
414+
415+
public function test_it_throws_when_underlying_store_does_not_support_locks()
416+
{
417+
$this->freezeTime();
418+
$exceptions = [];
419+
Exceptions::reportable(function (Throwable $e) use (&$exceptions) {
420+
$exceptions[] = $e;
421+
});
422+
Config::set('cache.stores.no-lock', ['driver' => 'no-lock']);
423+
Cache::extend('no-lock', fn () => Cache::repository(new class implements Store {
424+
public function get($key)
425+
{
426+
return Cache::get(...func_get_args());
427+
}
428+
429+
public function many(array $keys)
430+
{
431+
return Cache::many(...func_get_args());
432+
}
433+
434+
public function put($key, $value, $seconds) {
435+
436+
return Cache::put(...func_get_args());
437+
}
438+
439+
public function putMany(array $values, $seconds) {
440+
return Cache::putMany(...func_get_args());
441+
}
442+
443+
public function increment($key, $value = 1) {
444+
445+
return Cache::increment(...func_get_args());
446+
}
447+
448+
public function decrement($key, $value = 1) {
449+
return Cache::decrement(...func_get_args());
450+
}
451+
452+
public function forever($key, $value) {
453+
return Cache::forever(...func_get_args());
454+
455+
}
456+
457+
public function forget($key) {
458+
return Cache::forget(...func_get_args());
459+
}
460+
461+
public function flush() {
462+
return Cache::flush(...func_get_args());
463+
464+
}
465+
466+
public function getPrefix() {
467+
return Cache::getPrefix(...func_get_args());
468+
}
469+
}));
470+
Cache::flexible('key', [10, 20], 'value-1');
471+
472+
$this->travel(11)->seconds();
473+
Cache::memo('no-lock')->flexible('key', [10, 20], 'value-2');
474+
defer()->invoke();
475+
$value = Cache::get('key');
476+
477+
$this->assertCount(1, $exceptions);
478+
$this->assertInstanceOf(BadMethodCallException::class, $exceptions[0]);
479+
$this->assertSame('This cache store does not support locks.', $exceptions[0]->getMessage());
480+
}
481+
482+
public function test_it_supports_with_flexible()
483+
{
484+
$this->freezeTime();
485+
Cache::flexible('key', [10, 20], 'value-1');
486+
487+
$this->travel(11)->seconds();
488+
Cache::memo()->flexible('key', [10, 20], 'value-2');
489+
defer()->invoke();
490+
$value = Cache::get('key');
491+
492+
$this->assertSame('value-2', $value);
493+
}
409494
}

0 commit comments

Comments
 (0)