[Cache] add DeflateMarshaller - remove phpredis compression

This commit is contained in:
Nicolas Grekas 2019-10-26 16:49:03 +02:00
parent 0a1de38a5b
commit 452c863639
5 changed files with 118 additions and 10 deletions

View File

@ -15,6 +15,7 @@ use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Response\Status;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
use Symfony\Component\Cache\Traits\RedisTrait;
@ -68,6 +69,16 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, \get_class($redisClient->getConnection())));
}
if (\defined('Redis::OPT_COMPRESSION') && ($redisClient instanceof \Redis || $redisClient instanceof \RedisArray || $redisClient instanceof \RedisCluster)) {
$compression = $redisClient->getOption(\Redis::OPT_COMPRESSION);
foreach (\is_array($compression) ? $compression : [$compression] as $c) {
if (\Redis::COMPRESSION_NONE !== $c) {
throw new InvalidArgumentException(sprintf('phpredis compression must be disabled when using "%s", use "%s" instead.', \get_class($this), DeflateMarshaller::class));
}
}
}
$this->init($redisClient, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller));
}

View File

@ -8,6 +8,8 @@ CHANGELOG
* added argument `$prefix` to `AdapterInterface::clear()`
* improved `RedisTagAwareAdapter` to support Redis server >= 2.8 and up to 4B items per tag
* added `TagAwareMarshaller` for optimized data storage when using `AbstractTagAwareAdapter`
* added `DeflateMarshaller` to compress serialized values
* removed support for phpredis 4 `compression`
* [BC BREAK] `RedisTagAwareAdapter` is not compatible with `RedisCluster` from `Predis` anymore, use `phpredis` instead
4.3.0

View File

@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Marshaller;
use Symfony\Component\Cache\Exception\CacheException;
/**
* Compresses values using gzdeflate().
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class DeflateMarshaller implements MarshallerInterface
{
private $marshaller;
public function __construct(MarshallerInterface $marshaller)
{
if (!\function_exists('gzdeflate')) {
throw new CacheException('The "zlib" PHP extension is not loaded.');
}
$this->marshaller = $marshaller;
}
/**
* {@inheritdoc}
*/
public function marshall(array $values, ?array &$failed): array
{
return array_map('gzdeflate', $this->marshaller->marshall($values, $failed));
}
/**
* {@inheritdoc}
*/
public function unmarshall(string $value)
{
if (false !== $inflatedValue = @gzinflate($value)) {
$value = $inflatedValue;
}
return $this->marshaller->unmarshall($value);
}
}

View File

@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Marshaller;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
/**
* @requires extension zlib
*/
class DeflateMarshallerTest extends TestCase
{
public function testMarshall()
{
$defaultMarshaller = new DefaultMarshaller();
$deflateMarshaller = new DeflateMarshaller($defaultMarshaller);
$values = ['abc' => [str_repeat('def', 100)]];
$failed = [];
$defaultResult = $defaultMarshaller->marshall($values, $failed);
$deflateResult = $deflateMarshaller->marshall($values, $failed);
$deflateResult['abc'] = gzinflate($deflateResult['abc']);
$this->assertSame($defaultResult, $deflateResult);
}
public function testUnmarshall()
{
$defaultMarshaller = new DefaultMarshaller();
$deflateMarshaller = new DeflateMarshaller($defaultMarshaller);
$values = ['abc' => [str_repeat('def', 100)]];
$defaultResult = $defaultMarshaller->marshall($values, $failed);
$deflateResult = $deflateMarshaller->marshall($values, $failed);
$this->assertSame($values['abc'], $deflateMarshaller->unmarshall($deflateResult['abc']));
$this->assertSame($values['abc'], $deflateMarshaller->unmarshall($defaultResult['abc']));
}
}

View File

@ -34,7 +34,6 @@ trait RedisTrait
'timeout' => 30,
'read_timeout' => 0,
'retry_interval' => 0,
'compression' => true,
'tcp_keepalive' => 0,
'lazy' => null,
'redis_cluster' => false,
@ -197,9 +196,6 @@ trait RedisTrait
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
}
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
}
return true;
};
@ -225,9 +221,6 @@ trait RedisTrait
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
}
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
}
} elseif (is_a($class, \RedisCluster::class, true)) {
$initializer = function () use ($class, $params, $dsn, $hosts) {
foreach ($hosts as $i => $host) {
@ -243,9 +236,6 @@ trait RedisTrait
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
}
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
}
switch ($params['failover']) {
case 'error': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_ERROR); break;
case 'distribute': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE); break;