8000 [Cache] Add `\Relay\Cluster` support · symfony/symfony@f4a76e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit f4a76e0

Browse files
dorrogerayfabpot
authored andcommitted
[Cache] Add \Relay\Cluster support
1 parent c0c0a8f commit f4a76e0

15 files changed

+1572
-20
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class RedisAdapter extends AbstractAdapter
1818
{
1919
use RedisTrait;
2020

21-
public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Relay\Relay $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null)
21+
public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Relay\Relay|\Relay\Cluster $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null)
2222
{
2323
$this->init($redis, $namespace, $defaultLifetime, $marshaller);
2424
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
6060
private string $redisEvictionPolicy;
6161

6262
public function __construct(
63-
\Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis,
63+
\Redis|Relay|\Relay\Cluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis,
6464
private string $namespace = '',
6565
int $defaultLifetime = 0,
6666
?MarshallerInterface $marshaller = null,
@@ -69,7 +69,7 @@ public function __construct(
6969
throw new InvalidArgumentException(\sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection())));
7070
}
7171

72-
$isRelay = $redis instanceof Relay;
72+
$isRelay = $redis instanceof Relay || $redis instanceof \Relay\Cluster;
7373
if ($isRelay || \defined('Redis::OPT_COMPRESSION') && \in_array($redis::class, [\Redis::class, \RedisArray::class, \RedisCluster::class], true)) {
7474
$compression = $redis->getOption($isRelay ? Relay::OPT_COMPRESSION : \Redis::OPT_COMPRESSION);
7575

@@ -225,7 +225,7 @@ protected function doInvalidate(array $tagIds): bool
225225
$results = $this->pipeline(function () use ($tagIds, $lua) {
226226
if ($this->redis instanceof \Predis\ClientInterface) {
227227
$prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : '';
228-
} elseif (\is_array($prefix = $this->redis->getOption($this->redis instanceof Relay ? Relay::OPT_PREFIX : \Redis::OPT_PREFIX) ?? '')) {
228+
} elseif (\is_array($prefix = $this->redis->getOption(($this->redis instanceof Relay || $this->redis instanceof \Relay\Cluster) ? Relay::OPT_PREFIX : \Redis::OPT_PREFIX) ?? '')) {
229229
$prefix = current($prefix);
230230
}
231231

src/Symfony/Component/Cache/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Add support for `\Relay\Cluster` in `RedisAdapter`
8+
49
7.2
510
---
611

src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTestCase.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
1313

1414
use Psr\Cache\CacheItemPoolInterface;
1515
use Relay\Relay;
16+
use Relay\Cluster as RelayCluster;
1617
use Symfony\Component\Cache\Adapter\RedisAdapter;
1718

1819
abstract class AbstractRedisAdapterTestCase extends AdapterTestCase
@@ -23,7 +24,7 @@ abstract class AbstractRedisAdapterTestCase extends AdapterTestCase
2324
'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
2425
];
2526

26-
protected static \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis;
27+
protected static \Redis|Relay|RelayCluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis;
2728

2829
public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
2930
{
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Adapter;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
16+
use Symfony\Component\Cache\Traits\RelayClusterProxy;
17+
18+
/**
19+
* @requires extension relay
20+
*
21+
* @group integration
22+
*/
23+
class RedisTagAwareRelayClusterAdapterTest extends RelayClusterAdapterTest
24+
{
25+
use TagAwareTestTrait;
26+
27+
protected function setUp(): void
28+
{
29+
parent::setUp();
30+
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
31+
}
32+
33+
public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
34+
{
35+
$this->assertInstanceOf(RelayClusterProxy::class, self::$redis);
36+
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
37+
38+
return $adapter;
39+
}
40+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Adapter;
13+
14+
use Relay\Relay;
15+
use Relay\Cluster as RelayCluster;
16+
use Psr\Cache\CacheItemPoolInterface;
17+
use Symfony\Component\Cache\Adapter\AbstractAdapter;
18+
use Symfony\Component\Cache\Adapter\RedisAdapter;
19+
use Symfony\Component\Cache\Exception\InvalidArgumentException;
20+
use Symfony\Component\Cache\Traits\RelayClusterProxy;
21+
22+
/**
23+
* @requires extension relay
24+
*
25+
* @group integration
26+
*/
27+
class RelayClusterAdapterTest extends AbstractRedisAdapterTestCase
28+
{
29+
public static function setUpBeforeClass(): void
30+
{
31+
if (!class_exists(RelayCluster::class)) {
32+
self::markTestSkipped('The Relay\Cluster class is required.');
33+
}
34+
if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
35+
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
36+
}
37+
38+
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true, 'class' => RelayCluster::class]);
39+
self::$redis->setOption(Relay::OPT_PREFIX, 'prefix_');
40+
}
41+
42+
public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
43+
{
44+
$this->assertInstanceOf(RelayClusterProxy::class, self::$redis);
45+
$adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
46+
47+
return $adapter;
48+
}
49+
50+
/**
51+
* @dataProvider provideFailedCreateConnection
52+
*/
53+
public function testFailedCreateConnection(string $dsn)
54+
{
55+
$this->expectException(InvalidArgumentException::class);
56+
$this->expectExceptionMessage('Relay cluster connection failed:');
57+
RedisAdapter::createConnection($dsn);
58+
}
59+
60+
public static function provideFailedCreateConnection(): array
61+
{
62+
return [
63+
['redis://localhost:1234?redis_cluster=1&class=Relay\Cluster'],
64+
['redis://foo@localhost?redis_cluster=1&class=Relay\Cluster'],
65+
['redis://localhost/123?redis_cluster=1&class=Relay\Cluster'],
66+
];
67+
}
68+
}

src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Relay\Relay;
16+
use Relay\Cluster as RelayCluster;
1617
use Symfony\Component\Cache\Traits\RedisProxyTrait;
18+
use Symfony\Component\Cache\Traits\RelayClusterProxy;
1719
use Symfony\Component\Cache\Traits\RelayProxy;
1820
use Symfony\Component\VarExporter\LazyProxyTrait;
1921
use Symfony\Component\VarExporter\ProxyHelper;
@@ -121,4 +123,52 @@ public function testRelayProxy()
121123

122124
$this->assertEquals($expectedProxy, $proxy);
123125
}
126+
127+
128+
/**
129+
* @requires extension relay
130+
*/
131+
public function testRelayClusterProxy()
132+
{
133+
$proxy = file_get_contents(\dirname(__DIR__, 2).'/Traits/RelayClusterProxy.php');
134+
$proxy = substr($proxy, 0, 2 + strpos($proxy, '}'));
135+
$expectedProxy = $proxy;
136+
$methods = [];
137+
$expectedMethods = [];
138+
139+
foreach ((new \ReflectionClass(RelayClusterProxy::class))->getMethods() as $method) {
140+
if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) {
141+
continue;
142+
}
143+
144+
$return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return ';
145+
$expectedMethods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<<EOPHP
146+
{
147+
{$return}\$this->initializeLazyObject()->{$method->name}({$args});
148+
}
149+
150+
EOPHP;
151+
}
152+
153+
foreach ((new \ReflectionClass(RelayCluster::class))->getMethods() as $method) {
154+
if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) {
155+
continue;
156+
}
157+
$return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return ';
158+
$methods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<<EOPHP
159+
{
160+
{$return}\$this->initializeLazyObject()->{$method->name}({$args});
161+
}
162+
163+
EOPHP;
164+
}
165+
166+
uksort($methods, 'strnatcmp');
167+
$proxy .= implode('', $methods)."}\n";
168+
169+
uksort($expectedMethods, 'strnatcmp');
170+
$expectedProxy .= implode('', $expectedMethods)."}\n";
171+
172+
$this->assertEquals($expectedProxy, $proxy);
173+
}
124174
}

0 commit comments

Comments
 (0)
0