From 961eb0ec6a76b5808607a8628b69a205d5906544 Mon Sep 17 00:00:00 2001 From: Jack Gersten Date: Fri, 26 Jan 2024 12:53:03 -0800 Subject: [PATCH] Fix redis tag cache ttls in past no getting flushed --- src/Illuminate/Cache/RedisTagSet.php | 6 +++--- src/Illuminate/Cache/RedisTaggedCache.php | 20 ++++++++++++++++++-- tests/Integration/Cache/RedisStoreTest.php | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Cache/RedisTagSet.php b/src/Illuminate/Cache/RedisTagSet.php index bf4c53869361..b5fd0e2593bc 100644 --- a/src/Illuminate/Cache/RedisTagSet.php +++ b/src/Illuminate/Cache/RedisTagSet.php @@ -11,13 +11,13 @@ class RedisTagSet extends TagSet * Add a reference entry to the tag set's underlying sorted set. * * @param string $key - * @param int $ttl + * @param int|null $ttl * @param string $updateWhen * @return void */ - public function addEntry(string $key, int $ttl = 0, $updateWhen = null) + public function addEntry(string $key, int $ttl = null, $updateWhen = null) { - $ttl = $ttl > 0 ? Carbon::now()->addSeconds($ttl)->getTimestamp() : -1; + $ttl = is_null($ttl) ? -1 : Carbon::now()->addSeconds($ttl)->getTimestamp(); foreach ($this->tagIds() as $tagKey) { if ($updateWhen) { diff --git a/src/Illuminate/Cache/RedisTaggedCache.php b/src/Illuminate/Cache/RedisTaggedCache.php index b8120be95c03..75c1001ce747 100644 --- a/src/Illuminate/Cache/RedisTaggedCache.php +++ b/src/Illuminate/Cache/RedisTaggedCache.php @@ -14,9 +14,19 @@ class RedisTaggedCache extends TaggedCache */ public function add($key, $value, $ttl = null) { + $seconds = null; + + if ($ttl !== null) { + $seconds = $this->getSeconds($ttl); + + if ($seconds <= 0) { + return false; + } + } + $this->tags->addEntry( $this->itemKey($key), - ! is_null($ttl) ? $this->getSeconds($ttl) : 0 + $seconds ); return parent::add($key, $value, $ttl); @@ -36,9 +46,15 @@ public function put($key, $value, $ttl = null) return $this->forever($key, $value); } + $seconds = $this->getSeconds($ttl); + + if ($seconds <= 0) { + return false; + } + $this->tags->addEntry( $this->itemKey($key), - $this->getSeconds($ttl) + $seconds ); return parent::put($key, $value, $ttl); diff --git a/tests/Integration/Cache/RedisStoreTest.php b/tests/Integration/Cache/RedisStoreTest.php index c8c7abb13f62..dd0a1943b246 100644 --- a/tests/Integration/Cache/RedisStoreTest.php +++ b/tests/Integration/Cache/RedisStoreTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Integration\Cache; +use DateTime; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Redis; @@ -139,6 +140,27 @@ public function testIncrementedTagEntriesProperlyTurnStale() $this->assertEquals(0, count($keyCount)); } + public function testPastTtlTagEntriesAreNotAdded() + { + Cache::store('redis')->clear(); + + Cache::store('redis')->tags(['votes'])->add('person-1', 0, new DateTime('yesterday')); + + $keyCount = Cache::store('redis')->connection()->keys('*'); + $this->assertEquals(0, count($keyCount)); + } + + public function testPutPastTtlTagEntriesProperlyTurnStale() + { + Cache::store('redis')->clear(); + + Cache::store('redis')->tags(['votes'])->put('person-1', 0, new DateTime('yesterday')); + Cache::store('redis')->tags(['votes'])->flushStale(); + + $keyCount = Cache::store('redis')->connection()->keys('*'); + $this->assertEquals(0, count($keyCount)); + } + public function testTagsCanBeFlushedBySingleKey() { Cache::store('redis')->clear();