bug #34403 [Cache] Redis Tag Aware warn on wrong eviction policy (andrerom)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[Cache] Redis Tag Aware warn on wrong eviction policy

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| Deprecations? | no
| Tickets       | n.a.
| License       | MIT
| Doc PR        | n.a.

Adds validation to make sure Redis has been setup with the supported eviction policy to avoid surprises when cache suddenly is inconsistent.

This PR replaces #34178, and instead of checking in constructor and throwing it only checks on save, warns about this and refuses to save cache as suggested on the other PR.

TODO:
- [x] ~Adapt test setups for this to set correct eviction policy~ _It already uses default noeviction_

Commits
-------

e77f6de1e8 [Cache] Redis Tag Aware warn on wrong eviction policy
This commit is contained in:
Nicolas Grekas 2019-11-16 09:53:59 +01:00
commit 278dcfb380
1 changed files with 29 additions and 0 deletions

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Adapter;
use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Response\Status;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
@ -58,6 +59,11 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
*/
private const DEFAULT_CACHE_TTL = 8640000;
/**
* @var string|null detected eviction policy used on Redis server
*/
private $redisEvictionPolicy;
/**
* @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redisClient The redis client
* @param string $namespace The default namespace
@ -87,6 +93,13 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
*/
protected function doSave(array $values, ?int $lifetime, array $addTagData = [], array $delTagData = []): array
{
$eviction = $this->getRedisEvictionPolicy();
if ('noeviction' !== $eviction && 0 !== strpos($eviction, 'volatile-')) {
CacheItem::log($this->logger, sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies', $eviction));
return false;
}
// serialize values
if (!$serialized = $this->marshaller->marshall($values, $failed)) {
return $failed;
@ -260,4 +273,20 @@ EOLUA;
return $newIds;
}
private function getRedisEvictionPolicy(): string
{
if (null !== $this->redisEvictionPolicy) {
return $this->redisEvictionPolicy;
}
foreach ($this->getHosts() as $host) {
$info = $host->info('Memory');
$info = isset($info['Memory']) ? $info['Memory'] : $info;
return $this->redisEvictionPolicy = $info['maxmemory_policy'];
}
return $this->redisEvictionPolicy = '';
}
}