From b0029943f9272078663e173664b5aeff6359ef7b Mon Sep 17 00:00:00 2001 From: David <75451291+dulkoss@users.noreply.github.com> Date: Thu, 25 Apr 2024 20:25:21 +0200 Subject: [PATCH 1/3] doc comments --- src/CachedComponent.php | 5 +---- src/CachesValue.php | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/CachedComponent.php b/src/CachedComponent.php index 2ed4c82..884e34e 100644 --- a/src/CachedComponent.php +++ b/src/CachedComponent.php @@ -5,15 +5,12 @@ use Illuminate\Support\HtmlString; use Illuminate\View\Component; -/** - * @method string render() - */ abstract class CachedComponent extends Component { use CachesValue; /** {@inheritdoc} */ - public function resolveView(): \Illuminate\Contracts\View\View|HtmlString|\Illuminate\Contracts\Support\Htmlable|\Closure|string + public function resolveView() { if ( $this->isUpdating || diff --git a/src/CachesValue.php b/src/CachesValue.php index 29b7c8d..b546612 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -53,7 +53,7 @@ trait CachesValue * Update the cached value, this method expects an event if * the cacher is not static. * - * @internal You shouldn't call this yourself. + * @internal You shouldn't call this yourself, use the `CachesValue::update` method instead. */ final public function handle($event = null): mixed { From ff866867f25b7cb5a3657c73be1d91620e5fe8be Mon Sep 17 00:00:00 2001 From: David <75451291+dulkoss@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:51:44 +0200 Subject: [PATCH 2/3] add tests + fixes --- src/CachedComponent.php | 3 ++ src/CachesValue.php | 55 +++++++++++++++++---------- src/PermanentCache.php | 17 +++++---- tests/Unit/ReactiveCacheTest.php | 65 ++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 tests/Unit/ReactiveCacheTest.php diff --git a/src/CachedComponent.php b/src/CachedComponent.php index 884e34e..325a719 100644 --- a/src/CachedComponent.php +++ b/src/CachedComponent.php @@ -5,6 +5,9 @@ use Illuminate\Support\HtmlString; use Illuminate\View\Component; +/** + * @method mixed get(array $parameters = [], bool $update = false) + */ abstract class CachedComponent extends Component { use CachesValue; diff --git a/src/CachesValue.php b/src/CachesValue.php index b546612..8408c62 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -5,6 +5,7 @@ use Illuminate\Bus\Queueable; use Illuminate\Console\Scheduling\CallbackEvent; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\PendingDispatch; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Cache; @@ -44,10 +45,19 @@ trait CachesValue */ protected $expression = null; - /** @var array */ + /** + * The parameters this cache should be stored with. + * + * @var array + */ protected $parameters = []; - private bool $isUpdating = false; + /** + * Indicates whether this cache is currently updating or not. + * + * @var bool + */ + private $isUpdating = false; /** * Update the cached value, this method expects an event if @@ -55,7 +65,7 @@ trait CachesValue * * @internal You shouldn't call this yourself, use the `CachesValue::update` method instead. */ - final public function handle($event = null): mixed + final public function handle($event = null): void { $this->isUpdating = true; @@ -68,7 +78,7 @@ final public function handle($event = null): mixed : $this->run($event); if (is_null($value)) { - return null; + return; } Cache::driver($driver)->forever($cacheKey, $value); @@ -76,8 +86,6 @@ final public function handle($event = null): mixed PermanentCacheUpdated::dispatch($this); $this->isUpdating = false; - - return $value; } public function getParameters() @@ -113,20 +121,16 @@ public function shouldBeUpdating(): bool /** * Manually force a static cache to update. */ - final public static function update($parameters = []): mixed + final public static function update($parameters = []): ?PendingDispatch { $instance = app()->make(static::class, $parameters); - if ( - app()->runningInConsole() && - is_subclass_of(static::class, ShouldQueue::class) - ) { - dispatch($instance); - + if (! is_subclass_of(static::class, ShouldQueue::class)) { + $instance->handle(); return null; } - return $instance->handle(); + return dispatch($instance); } /** @@ -147,16 +151,27 @@ final public static function get($default = null, bool $update = false): mixed $cache = Cache::driver($driver); - if ( - $update || - ! $cache->has($cacheKey) - ) { - return static::update($parameters ?? []); + if ($update && ! $cache->has($cacheKey)) { + static::update($parameters ?? [])->onConnection('sync'); } return $cache->get($cacheKey, $default); } + /** + * Force an update of the cache and return the updated value. + * + * @return V|mixed + */ + final public static function updateAndGet($parameters = []): mixed + { + [$driver, $cacheKey] = self::store($parameters); + + static::update($parameters)->onConnection('sync'); + + return Cache::driver($driver)->get($cacheKey); + } + /** * Get the cached value this cacher provides. * @@ -237,7 +252,7 @@ private static function parseCacheString($class, ?string $store, ?array $paramet } $cacheDriver ??= config('cache.default'); - $cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(snake_case($class))); + $cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(\Str::snake($class))); if ($parameters) { $cacheKey .= ':'.http_build_query($parameters); diff --git a/src/PermanentCache.php b/src/PermanentCache.php index 354a1fc..a21b537 100755 --- a/src/PermanentCache.php +++ b/src/PermanentCache.php @@ -8,8 +8,11 @@ class PermanentCache { - public function __construct(protected SplObjectStorage $cachers, protected Application $app) - { + public function __construct( + protected SplObjectStorage $cachers, + protected Application $app, + ) { + // } /** @@ -33,18 +36,18 @@ public function caches($registeredCaches): self $cacher = array_key_first($parameters); $parameters = array_shift($parameters); } else { - $cacher = array_first($parameters); + $cacher = \Arr::first($parameters); $parameters = []; } } - $cacher = $this->app->make($cacher, $parameters); + $cacherInstance = $this->app->make($cacher, $parameters); - if ([] !== $events = $cacher::getListenerEvents()) { - Event::listen($events, fn () => $cacher->update($parameters)); + if ([] !== $events = $cacherInstance->getListenerEvents()) { + Event::listen($events, fn ($event) => $cacherInstance->handle($event)); } - $this->cachers[$cacher] = $events; + $this->cachers[$cacherInstance] = $events; } } diff --git a/tests/Unit/ReactiveCacheTest.php b/tests/Unit/ReactiveCacheTest.php new file mode 100644 index 0000000..b17f522 --- /dev/null +++ b/tests/Unit/ReactiveCacheTest.php @@ -0,0 +1,65 @@ +clear(); + (fn () => $this->cachers = new \SplObjectStorage)->call(app(\Vormkracht10\PermanentCache\PermanentCache::class)); +}); + +class TestEvent {} + +class TestCache extends Cached { + protected $store = 'array:test'; + + public function run(TestEvent $_): mixed + { + return 'it works!'; + } +} + +test('caches (listeners) get registered properly when using the PermanentCache facade', function () { + $events = Event::fake([TestEvent::class]); + + PermanentCache::caches([TestCache::class]); + + $caches = PermanentCache::configuredCaches(); + + expect($caches) + ->count()->toBe(1) + ->current()->toBeInstanceOf(TestCache::class) + ->and($events)->hasListeners(TestEvent::class); +}); + +test('a cache will get updated when an event it\'s listening to gets fired', function () { + global $pass; + $pass = false; + + class T extends Cached { + public function run(TestEvent $_) + { + global $pass; + $pass = true; + } + } + + Event::fakeExcept(TestEvent::class); + PermanentCache::caches(T::class); + event(new TestEvent); + + expect($pass)->toBeTrue(); + unset($pass); +}); + +test('a cache will dispatch the updating and updated events when it gets invoked', function () { + Event::fakeExcept(TestEvent::class); + Permanentcache::caches(TestCache::class); + event(new TestEvent); + Event::assertDispatchedTimes(PermanentCacheUpdating::class, times: 1); + Event::assertDispatchedTimes(PermanentCacheUpdated::class, times : 1); +}); From 87bb6835e6cf20ed0ba1fc567c7141c36c26a261 Mon Sep 17 00:00:00 2001 From: david-d-h Date: Thu, 25 Apr 2024 20:52:10 +0000 Subject: [PATCH 3/3] Fix styling --- src/CachesValue.php | 1 + tests/Unit/ReactiveCacheTest.php | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index 8408c62..380c48a 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -127,6 +127,7 @@ final public static function update($parameters = []): ?PendingDispatch if (! is_subclass_of(static::class, ShouldQueue::class)) { $instance->handle(); + return null; } diff --git a/tests/Unit/ReactiveCacheTest.php b/tests/Unit/ReactiveCacheTest.php index b17f522..e7e8b47 100644 --- a/tests/Unit/ReactiveCacheTest.php +++ b/tests/Unit/ReactiveCacheTest.php @@ -1,7 +1,7 @@ $this->cachers = new \SplObjectStorage)->call(app(\Vormkracht10\PermanentCache\PermanentCache::class)); }); -class TestEvent {} +class TestEvent +{ +} -class TestCache extends Cached { +class TestCache extends Cached +{ protected $store = 'array:test'; public function run(TestEvent $_): mixed @@ -40,7 +43,8 @@ public function run(TestEvent $_): mixed global $pass; $pass = false; - class T extends Cached { + class T extends Cached + { public function run(TestEvent $_) { global $pass;