diff --git a/src/Illuminate/Cache/RedisStore.php b/src/Illuminate/Cache/RedisStore.php index 4f18dcf5d1b9..d4296fc78509 100755 --- a/src/Illuminate/Cache/RedisStore.php +++ b/src/Illuminate/Cache/RedisStore.php @@ -14,6 +14,7 @@ class RedisStore extends TaggableStore implements LockProvider { use RetrievesMultipleKeys { + many as private manyAlias; putMany as private putManyAlias; } @@ -92,6 +93,12 @@ public function many(array $keys) $connection = $this->connection(); + // Cluster connections do not support reading multiple values if the keys hash differently... + if ($connection instanceof PhpRedisClusterConnection || + $connection instanceof PredisClusterConnection) { + return $this->manyAlias($keys); + } + $values = $connection->mget(array_map(function ($key) { return $this->prefix.$key; }, $keys)); diff --git a/src/Illuminate/Cache/RedisTagSet.php b/src/Illuminate/Cache/RedisTagSet.php index 82369ff4ed00..8ea4c4ae9799 100644 --- a/src/Illuminate/Cache/RedisTagSet.php +++ b/src/Illuminate/Cache/RedisTagSet.php @@ -79,11 +79,18 @@ public function entries() */ public function flushStaleEntries() { - $this->store->connection()->pipeline(function ($pipe) { + $flushStaleEntries = function ($pipe) { foreach ($this->tagIds() as $tagKey) { $pipe->zremrangebyscore($this->store->getPrefix().$tagKey, 0, Carbon::now()->getTimestamp()); } - }); + }; + + $connection = $this->store->connection(); + if ($connection instanceof PhpRedisConnection) { + $flushStaleEntries($connection); + } else { + $connection->pipeline($flushStaleEntries); + } } /** diff --git a/src/Illuminate/Cache/RedisTaggedCache.php b/src/Illuminate/Cache/RedisTaggedCache.php index 7f4e30992a4a..61aaf735e890 100644 --- a/src/Illuminate/Cache/RedisTaggedCache.php +++ b/src/Illuminate/Cache/RedisTaggedCache.php @@ -193,8 +193,17 @@ protected function flushValues() ->map(fn (string $key) => $this->store->getPrefix().$key) ->chunk(1000); + $connection = $this->store->connection(); foreach ($entries as $cacheKeys) { - $this->store->connection()->del(...$cacheKeys); + if ($connection instanceof PredisClusterConnection) { + $connection->pipeline(function ($connection) use ($cacheKeys) { + foreach ($cacheKeys as $cacheKey) { + $connection->del($cacheKey); + } + }); + } else { + $connection->del(...$cacheKeys); + } } } diff --git a/src/Illuminate/Redis/Connections/PredisClusterConnection.php b/src/Illuminate/Redis/Connections/PredisClusterConnection.php index dbf91dc46f77..92212c56df8e 100644 --- a/src/Illuminate/Redis/Connections/PredisClusterConnection.php +++ b/src/Illuminate/Redis/Connections/PredisClusterConnection.php @@ -22,4 +22,20 @@ public function flushdb() $node->executeCommand(tap(new $command)->setArguments(func_get_args())); } } + + /** + * Returns the keys that match a certain pattern. + * + * @param string $pattern + * @return array + */ + public function keys(string $pattern) + { + $keys = []; + foreach ($this->client as $node) { + $keys[] = $node->keys($pattern); + } + + return array_merge(...$keys); + } } diff --git a/tests/Integration/Cache/MemoizedStoreTest.php b/tests/Integration/Cache/MemoizedStoreTest.php index e9ec1b435d51..74022ea8527d 100644 --- a/tests/Integration/Cache/MemoizedStoreTest.php +++ b/tests/Integration/Cache/MemoizedStoreTest.php @@ -13,8 +13,6 @@ use Illuminate\Cache\Events\WritingKey; use Illuminate\Contracts\Cache\Store; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; -use Illuminate\Redis\Connections\PhpRedisClusterConnection; -use Illuminate\Redis\Connections\PredisClusterConnection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Event; @@ -33,14 +31,9 @@ protected function setUp(): void $this->setUpRedis(); - $connection = $this->app['redis']->connection(); - $this->markTestSkippedWhen( - $connection instanceof PhpRedisClusterConnection || $connection instanceof PredisClusterConnection, - 'flushAll and many currently not supported for Redis Cluster connections', - ); - Config::set('cache.default', 'redis'); - Redis::flushAll(); + Redis::connection(Config::get('cache.stores.redis.connection'))->flushDb(); + Redis::connection(Config::get('cache.stores.redis.lock_connection'))->flushDb(); } protected function tearDown(): void diff --git a/tests/Integration/Cache/RedisStoreTest.php b/tests/Integration/Cache/RedisStoreTest.php index ede6e7c394f1..e4332b5b6b40 100644 --- a/tests/Integration/Cache/RedisStoreTest.php +++ b/tests/Integration/Cache/RedisStoreTest.php @@ -6,9 +6,7 @@ use Illuminate\Cache\RedisStore; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; use Illuminate\Redis\Connections\PhpRedisClusterConnection; -use Illuminate\Redis\Connections\PredisClusterConnection; use Illuminate\Support\Facades\Cache; -use Illuminate\Support\Facades\Redis; use Illuminate\Support\Sleep; use Mockery as m; use Orchestra\Testbench\TestCase; @@ -23,12 +21,6 @@ protected function setUp(): void { $this->afterApplicationCreated(function () { $this->setUpRedis(); - - $connection = $this->app['redis']->connection(); - $this->markTestSkippedWhen( - $connection instanceof PhpRedisClusterConnection || $connection instanceof PredisClusterConnection, - 'RedisStore currently does not support tags, many and some other on Redis Cluster cluster connections', - ); }); $this->beforeApplicationDestroyed(function () {