bug #40299 [Cache] Add server-commands support for Predis Replication Environments (DemigodCode)

This PR was merged into the 4.4 branch.

Discussion
----------

[Cache] Add server-commands support for Predis Replication Environments

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #35867
| License       | MIT
| Doc PR        |

This fix is for predis MasterSlaveConnections which don't allow to run server commands.
Due to that it's not possible to e.g. clear a cache with cache:pool:clear.

PhpRedis and Predis do not have the same interface, so have to check which implementation is used.
Furthermore, the getClientFor('master') works only for replicated redis instances.

Commits
-------

2ae5c33c80 [Cache] Add server-commands support for Predis Replication Environments
This commit is contained in:
Nicolas Grekas 2021-02-26 00:52:22 +01:00
commit 3fe1564912
2 changed files with 18 additions and 2 deletions

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Cache\Adapter;
use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Connection\Aggregate\ReplicationInterface;
use Predis\Response\Status;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Exception\LogicException;
@ -278,7 +279,14 @@ EOLUA;
return $this->redisEvictionPolicy;
}
foreach ($this->getHosts() as $host) {
$hosts = $this->getHosts();
$host = reset($hosts);
if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
// Predis supports info command only on the master in replication environments
$hosts = [$host->getClientFor('master')];
}
foreach ($hosts as $host) {
$info = $host->info('Memory');
$info = $info['Memory'] ?? $info;

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Cache\Traits;
use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\RedisCluster;
use Predis\Connection\Aggregate\ReplicationInterface;
use Predis\Response\Status;
use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
@ -367,7 +368,14 @@ trait RedisTrait
$evalArgs = [[$namespace], 0];
}
foreach ($this->getHosts() as $host) {
$hosts = $this->getHosts();
$host = reset($hosts);
if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
// Predis supports info command only on the master in replication environments
$hosts = [$host->getClientFor('master')];
}
foreach ($hosts as $host) {
if (!isset($namespace[0])) {
$cleared = $host->flushDb() && $cleared;
continue;