Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f4a76e0

Browse filesBrowse files
dorrogerayfabpot
authored andcommitted
[Cache] Add \Relay\Cluster support
1 parent c0c0a8f commit f4a76e0
Copy full SHA for f4a76e0

15 files changed

+1572
-20
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Adapter/RedisAdapter.php
+1-1
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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php
+3-3
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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/CHANGELOG.md
+5
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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTestCase.php
+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
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
{
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+
}
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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php
+50
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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.