Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 38bd52e

Browse files
feature #34133 [Cache] add DeflateMarshaller - remove phpredis compression (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [Cache] add DeflateMarshaller - remove phpredis compression | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - phpredis compression doesn't play well with lua scripting as used in #33939 Let's remove it and provide a `DeflateMarshaller` instead. Ppl can use it via decoration: ```yaml services: Symfony\Component\Cache\Marshaller\DeflateMarshaller: decorates: cache.default_marshaller arguments: ['@symfony\Component\Cache\Marshaller\DeflateMarshaller.inner'] ``` It's not enabled by default because that might break pools that are shared between different apps. /cc @andrerom FYI Commits ------- 452c863 [Cache] add DeflateMarshaller - remove phpredis compression
2 parents 8cf0698 + 452c863 commit 38bd52e

File tree

5 files changed

+118
-10
lines changed

5 files changed

+118
-10
lines changed

src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Predis\Connection\Aggregate\PredisCluster;
1616
use Predis\Response\Status;
1717
use Symfony\Component\Cache\Exception\InvalidArgumentException;
18+
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
1819
use Symfony\Component\Cache\Marshaller\MarshallerInterface;
1920
use Symfony\Component\Cache\Marshaller\TagAwareMarshaller;
2021
use Symfony\Component\Cache\Traits\RedisTrait;
@@ -68,6 +69,16 @@ public function __construct($redisClient, string $namespace = '', int $defaultLi
6869
throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, \get_class($redisClient->getConnection())));
6970
}
7071

72+
if (\defined('Redis::OPT_COMPRESSION') && ($redisClient instanceof \Redis || $redisClient instanceof \RedisArray || $redisClient instanceof \RedisCluster)) {
73+
$compression = $redisClient->getOption(\Redis::OPT_COMPRESSION);
74+
75+
foreach (\is_array($compression) ? $compression : [$compression] as $c) {
76+
if (\Redis::COMPRESSION_NONE !== $c) {
77+
throw new InvalidArgumentException(sprintf('phpredis compression must be disabled when using "%s", use "%s" instead.', \get_class($this), DeflateMarshaller::class));
78+
}
79+
}
80+
}
81+
7182
$this->init($redisClient, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller));
7283
}
7384

src/Symfony/Component/Cache/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ CHANGELOG
88
* added argument `$prefix` to `AdapterInterface::clear()`
99
* improved `RedisTagAwareAdapter` to support Redis server >= 2.8 and up to 4B items per tag
1010
* added `TagAwareMarshaller` for optimized data storage when using `AbstractTagAwareAdapter`
11+
* added `DeflateMarshaller` to compress serialized values
12+
* removed support for phpredis 4 `compression`
1113
* [BC BREAK] `RedisTagAwareAdapter` is not compatible with `RedisCluster` from `Predis` anymore, use `phpredis` instead
1214

1315
4.3.0
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Marshaller;
13+
14+
use Symfony\Component\Cache\Exception\CacheException;
15+
16+
/**
17+
* Compresses values using gzdeflate().
18+
*
19+
* @author Nicolas Grekas <[email protected]>
20+
*/
21+
class DeflateMarshaller implements MarshallerInterface
22+
{
23+
private $marshaller;
24+
25+
public function __construct(MarshallerInterface $marshaller)
26+
{
27+
if (!\function_exists('gzdeflate')) {
28+
throw new CacheException('The "zlib" PHP extension is not loaded.');
29+
}
30+
31+
$this->marshaller = $marshaller;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function marshall(array $values, ?array &$failed): array
38+
{
39+
return array_map('gzdeflate', $this->marshaller->marshall($values, $failed));
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*/
45+
public function unmarshall(string $value)
46+
{
47+
if (false !== $inflatedValue = @gzinflate($value)) {
48+
$value = $inflatedValue;
49+
}
50+
51+
return $this->marshaller->unmarshall($value);
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Tests\Marshaller;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
16+
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
17+
18+
/**
19+
* @requires extension zlib
20+
*/
21+
class DeflateMarshallerTest extends TestCase
22+
{
23+
public function testMarshall()
24+
{
25+
$defaultMarshaller = new DefaultMarshaller();
26+
$deflateMarshaller = new DeflateMarshaller($defaultMarshaller);
27+
28+
$values = ['abc' => [str_repeat('def', 100)]];
29+
30+
$failed = [];
31+
$defaultResult = $defaultMarshaller->marshall($values, $failed);
32+
33+
$deflateResult = $deflateMarshaller->marshall($values, $failed);
34+
$deflateResult['abc'] = gzinflate($deflateResult['abc']);
35+
36+
$this->assertSame($defaultResult, $deflateResult);
37+
}
38+
39+
public function testUnmarshall()
40+
{
41+
$defaultMarshaller = new DefaultMarshaller();
42+
$deflateMarshaller = new DeflateMarshaller($defaultMarshaller);
43+
44+
$values = ['abc' => [str_repeat('def', 100)]];
45+
46+
$defaultResult = $defaultMarshaller->marshall($values, $failed);
47+
$deflateResult = $deflateMarshaller->marshall($values, $failed);
48+
49+
$this->assertSame($values['abc'], $deflateMarshaller->unmarshall($deflateResult['abc']));
50+
$this->assertSame($values['abc'], $deflateMarshaller->unmarshall($defaultResult['abc']));
51+
}
52+
}

src/Symfony/Component/Cache/Traits/RedisTrait.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ trait RedisTrait
3434
'timeout' => 30,
3535
'read_timeout' => 0,
3636
'retry_interval' => 0,
37-
'compression' => true,
3837
'tcp_keepalive' => 0,
3938
'lazy' => null,
4039
'redis_cluster' => false,
@@ -197,9 +196,6 @@ public static function createConnection($dsn, array $options = [])
197196
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
198197
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
199198
}
200-
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
201-
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
202-
}
203199

204200
return true;
205201
};
@@ -225,9 +221,6 @@ public static function createConnection($dsn, array $options = [])
225221
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
226222
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
227223
}
228-
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
229-
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
230-
}
231224
} elseif (is_a($class, \RedisCluster::class, true)) {
232225
$initializer = function () use ($class, $params, $dsn, $hosts) {
233226
foreach ($hosts as $i => $host) {
@@ -243,9 +236,6 @@ public static function createConnection($dsn, array $options = [])
243236
if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
244237
$redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
245238
}
246-
if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
247-
$redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
248-
}
249239
switch ($params['failover']) {
250240
case 'error': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_ERROR); break;
251241
case 'distribute': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE); break;

0 commit comments

Comments
 (0)