[Cache] handle prefixed redis connections when clearing pools
This commit is contained in:
parent
c7cd08aa6e
commit
7527b5a4f9
@ -24,7 +24,7 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase
|
|||||||
|
|
||||||
protected static $redis;
|
protected static $redis;
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
}
|
}
|
||||||
@ -45,4 +45,18 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase
|
|||||||
{
|
{
|
||||||
self::$redis = null;
|
self::$redis = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runInSeparateProcess
|
||||||
|
*/
|
||||||
|
public function testClearWithPrefix()
|
||||||
|
{
|
||||||
|
$cache = $this->createCachePool(0, __FUNCTION__);
|
||||||
|
|
||||||
|
$cache->save($cache->getItem('foo')->set('bar'));
|
||||||
|
$this->assertTrue($cache->hasItem('foo'));
|
||||||
|
|
||||||
|
$cache->clear();
|
||||||
|
$this->assertFalse($cache->hasItem('foo'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class PredisAdapterTest extends AbstractRedisAdapterTest
|
|||||||
public static function setUpBeforeClass(): void
|
public static function setUpBeforeClass(): void
|
||||||
{
|
{
|
||||||
parent::setUpBeforeClass();
|
parent::setUpBeforeClass();
|
||||||
self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]);
|
self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')], ['prefix' => 'prefix_']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCreateConnection()
|
public function testCreateConnection()
|
||||||
|
@ -19,7 +19,7 @@ class PredisClusterAdapterTest extends AbstractRedisAdapterTest
|
|||||||
public static function setUpBeforeClass(): void
|
public static function setUpBeforeClass(): void
|
||||||
{
|
{
|
||||||
parent::setUpBeforeClass();
|
parent::setUpBeforeClass();
|
||||||
self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]);
|
self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]], ['prefix' => 'prefix_']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void
|
public static function tearDownAfterClass(): void
|
||||||
|
@ -24,7 +24,7 @@ class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest
|
|||||||
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
|
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true]);
|
self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true, 'prefix' => 'prefix_']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void
|
public static function tearDownAfterClass(): void
|
||||||
|
@ -27,7 +27,7 @@ class PredisTagAwareAdapterTest extends PredisAdapterTest
|
|||||||
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
|
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
|
||||||
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
@ -27,7 +27,7 @@ class PredisTagAwareClusterAdapterTest extends PredisClusterAdapterTest
|
|||||||
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
|
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
|
||||||
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
@ -32,7 +32,7 @@ class RedisAdapterSentinelTest extends AbstractRedisAdapterTest
|
|||||||
self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.');
|
self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.');
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['redis_sentinel' => $service]);
|
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['redis_sentinel' => $service, 'prefix' => 'prefix_']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidDSNHasBothClusterAndSentinel()
|
public function testInvalidDSNHasBothClusterAndSentinel()
|
||||||
|
@ -28,9 +28,13 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
|
|||||||
self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]);
|
self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
$adapter = parent::createCachePool($defaultLifetime);
|
if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
|
||||||
|
self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
$adapter = parent::createCachePool($defaultLifetime, $testMethod);
|
||||||
$this->assertInstanceOf(RedisProxy::class, self::$redis);
|
$this->assertInstanceOf(RedisProxy::class, self::$redis);
|
||||||
|
|
||||||
return $adapter;
|
return $adapter;
|
||||||
|
@ -23,5 +23,6 @@ class RedisArrayAdapterTest extends AbstractRedisAdapterTest
|
|||||||
self::markTestSkipped('The RedisArray class is required.');
|
self::markTestSkipped('The RedisArray class is required.');
|
||||||
}
|
}
|
||||||
self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]);
|
self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]);
|
||||||
|
self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,15 @@ class RedisClusterAdapterTest extends AbstractRedisAdapterTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true]);
|
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true]);
|
||||||
|
self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
|
if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
|
||||||
|
self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
|
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
|
||||||
$adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
|
||||||
|
@ -28,8 +28,12 @@ class RedisTagAwareAdapterTest extends RedisAdapterTest
|
|||||||
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
|
if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
|
||||||
|
self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertInstanceOf(RedisProxy::class, self::$redis);
|
$this->assertInstanceOf(RedisProxy::class, self::$redis);
|
||||||
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
|
||||||
|
@ -27,8 +27,12 @@ class RedisTagAwareArrayAdapterTest extends RedisArrayAdapterTest
|
|||||||
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
|
if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
|
||||||
|
self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertInstanceOf(\RedisArray::class, self::$redis);
|
$this->assertInstanceOf(\RedisArray::class, self::$redis);
|
||||||
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
|
||||||
|
@ -28,8 +28,12 @@ class RedisTagAwareClusterAdapterTest extends RedisClusterAdapterTest
|
|||||||
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
|
public function createCachePool(int $defaultLifetime = 0, string $testMethod = null): CacheItemPoolInterface
|
||||||
{
|
{
|
||||||
|
if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
|
||||||
|
self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
|
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
|
||||||
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
|
||||||
|
|
||||||
|
@ -45,4 +45,9 @@ class RedisClusterNodeProxy
|
|||||||
{
|
{
|
||||||
return $this->redis->scan($iIterator, $this->host, $strPattern, $iCount);
|
return $this->redis->scan($iIterator, $this->host, $strPattern, $iCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOption($name)
|
||||||
|
{
|
||||||
|
return $this->redis->getOption($name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,6 +362,11 @@ trait RedisTrait
|
|||||||
*/
|
*/
|
||||||
protected function doClear($namespace)
|
protected function doClear($namespace)
|
||||||
{
|
{
|
||||||
|
if ($this->redis instanceof \Predis\ClientInterface) {
|
||||||
|
$prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : '';
|
||||||
|
$prefixLen = \strlen($prefix);
|
||||||
|
}
|
||||||
|
|
||||||
$cleared = true;
|
$cleared = true;
|
||||||
$hosts = $this->getHosts();
|
$hosts = $this->getHosts();
|
||||||
$host = reset($hosts);
|
$host = reset($hosts);
|
||||||
@ -379,7 +384,11 @@ trait RedisTrait
|
|||||||
$info = $host->info('Server');
|
$info = $host->info('Server');
|
||||||
$info = $info['Server'] ?? $info;
|
$info = $info['Server'] ?? $info;
|
||||||
|
|
||||||
$pattern = $namespace.'*';
|
if (!$host instanceof \Predis\ClientInterface) {
|
||||||
|
$prefix = \defined('Redis::SCAN_PREFIX') && (\Redis::SCAN_PREFIX & $host->getOption(\Redis::OPT_SCAN)) ? '' : $host->getOption(\Redis::OPT_PREFIX);
|
||||||
|
$prefixLen = \strlen($host->getOption(\Redis::OPT_PREFIX) ?? '');
|
||||||
|
}
|
||||||
|
$pattern = $prefix.$namespace.'*';
|
||||||
|
|
||||||
if (!version_compare($info['redis_version'], '2.8', '>=')) {
|
if (!version_compare($info['redis_version'], '2.8', '>=')) {
|
||||||
// As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
|
// As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
|
||||||
@ -398,6 +407,11 @@ trait RedisTrait
|
|||||||
$keys = $keys[1];
|
$keys = $keys[1];
|
||||||
}
|
}
|
||||||
if ($keys) {
|
if ($keys) {
|
||||||
|
if ($prefixLen) {
|
||||||
|
foreach ($keys as $i => $key) {
|
||||||
|
$keys[$i] = substr($key, $prefixLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->doDelete($keys);
|
$this->doDelete($keys);
|
||||||
}
|
}
|
||||||
} while ($cursor = (int) $cursor);
|
} while ($cursor = (int) $cursor);
|
||||||
|
Reference in New Issue
Block a user