[Cache] add RedisClusterProxy to create lazy connections to Redis clusters
This commit is contained in:
parent
944b06d7fa
commit
239a022cc0
63
src/Symfony/Component/Cache/Traits/RedisClusterProxy.php
Normal file
63
src/Symfony/Component/Cache/Traits/RedisClusterProxy.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?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\Traits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alessandro Chitolina <alekitto@gmail.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class RedisClusterProxy
|
||||||
|
{
|
||||||
|
private $redis;
|
||||||
|
private $initializer;
|
||||||
|
|
||||||
|
public function __construct(\Closure $initializer)
|
||||||
|
{
|
||||||
|
$this->initializer = $initializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __call($method, array $args)
|
||||||
|
{
|
||||||
|
$this->redis ?: $this->redis = $this->initializer->__invoke();
|
||||||
|
|
||||||
|
return $this->redis->{$method}(...$args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
|
||||||
|
{
|
||||||
|
$this->redis ?: $this->redis = $this->initializer->__invoke();
|
||||||
|
|
||||||
|
return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scan(&$iIterator, $strPattern = null, $iCount = null)
|
||||||
|
{
|
||||||
|
$this->redis ?: $this->redis = $this->initializer->__invoke();
|
||||||
|
|
||||||
|
return $this->redis->scan($iIterator, $strPattern, $iCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
|
||||||
|
{
|
||||||
|
$this->redis ?: $this->redis = $this->initializer->__invoke();
|
||||||
|
|
||||||
|
return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
|
||||||
|
{
|
||||||
|
$this->redis ?: $this->redis = $this->initializer->__invoke();
|
||||||
|
|
||||||
|
return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount);
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,7 @@ trait RedisTrait
|
|||||||
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
|
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
|
||||||
throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
|
throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
|
||||||
}
|
}
|
||||||
if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy) {
|
if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy && !$redisClient instanceof RedisClusterProxy) {
|
||||||
throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, \is_object($redisClient) ? \get_class($redisClient) : \gettype($redisClient)));
|
throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, \is_object($redisClient) ? \get_class($redisClient) : \gettype($redisClient)));
|
||||||
}
|
}
|
||||||
$this->redis = $redisClient;
|
$this->redis = $redisClient;
|
||||||
@ -237,7 +237,7 @@ trait RedisTrait
|
|||||||
foreach ($this->redis->_hosts() as $host) {
|
foreach ($this->redis->_hosts() as $host) {
|
||||||
$hosts[] = $this->redis->_instance($host);
|
$hosts[] = $this->redis->_instance($host);
|
||||||
}
|
}
|
||||||
} elseif ($this->redis instanceof \RedisCluster) {
|
} elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
|
||||||
$hosts = array();
|
$hosts = array();
|
||||||
foreach ($this->redis->_masters() as $host) {
|
foreach ($this->redis->_masters() as $host) {
|
||||||
$hosts[] = $h = new \Redis();
|
$hosts[] = $h = new \Redis();
|
||||||
@ -330,7 +330,7 @@ trait RedisTrait
|
|||||||
{
|
{
|
||||||
$ids = array();
|
$ids = array();
|
||||||
|
|
||||||
if ($this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof RedisCluster)) {
|
if ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof RedisCluster)) {
|
||||||
// phpredis & predis don't support pipelining with RedisCluster
|
// phpredis & predis don't support pipelining with RedisCluster
|
||||||
// see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining
|
// see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining
|
||||||
// see https://github.com/nrk/predis/issues/267#issuecomment-123781423
|
// see https://github.com/nrk/predis/issues/267#issuecomment-123781423
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
||||||
|
|
||||||
use Predis\Response\ErrorInterface;
|
use Predis\Response\ErrorInterface;
|
||||||
|
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +46,8 @@ class RedisSessionHandler extends AbstractSessionHandler
|
|||||||
!$redis instanceof \RedisArray &&
|
!$redis instanceof \RedisArray &&
|
||||||
!$redis instanceof \RedisCluster &&
|
!$redis instanceof \RedisCluster &&
|
||||||
!$redis instanceof \Predis\Client &&
|
!$redis instanceof \Predis\Client &&
|
||||||
!$redis instanceof RedisProxy
|
!$redis instanceof RedisProxy &&
|
||||||
|
!$redis instanceof RedisClusterProxy
|
||||||
) {
|
) {
|
||||||
throw new \InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, \is_object($redis) ? \get_class($redis) : \gettype($redis)));
|
throw new \InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, \is_object($redis) ? \get_class($redis) : \gettype($redis)));
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Lock\Store;
|
namespace Symfony\Component\Lock\Store;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||||
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Lock\Exception\LockConflictedException;
|
use Symfony\Component\Lock\Exception\LockConflictedException;
|
||||||
@ -130,7 +131,12 @@ class RedisStore implements StoreInterface
|
|||||||
*/
|
*/
|
||||||
private function evaluate(string $script, string $resource, array $args)
|
private function evaluate(string $script, string $resource, array $args)
|
||||||
{
|
{
|
||||||
if ($this->redis instanceof \Redis || $this->redis instanceof \RedisCluster || $this->redis instanceof RedisProxy) {
|
if (
|
||||||
|
$this->redis instanceof \Redis ||
|
||||||
|
$this->redis instanceof \RedisCluster ||
|
||||||
|
$this->redis instanceof RedisProxy ||
|
||||||
|
$this->redis instanceof RedisClusterProxy
|
||||||
|
) {
|
||||||
return $this->redis->eval($script, array_merge(array($resource), $args), 1);
|
return $this->redis->eval($script, array_merge(array($resource), $args), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Lock\Store;
|
namespace Symfony\Component\Lock\Store;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\Traits\RedisClusterProxy;
|
||||||
use Symfony\Component\Cache\Traits\RedisProxy;
|
use Symfony\Component\Cache\Traits\RedisProxy;
|
||||||
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
@ -28,7 +29,14 @@ class StoreFactory
|
|||||||
*/
|
*/
|
||||||
public static function createStore($connection)
|
public static function createStore($connection)
|
||||||
{
|
{
|
||||||
if ($connection instanceof \Redis || $connection instanceof \RedisArray || $connection instanceof \RedisCluster || $connection instanceof \Predis\Client || $connection instanceof RedisProxy) {
|
if (
|
||||||
|
$connection instanceof \Redis ||
|
||||||
|
$connection instanceof \RedisArray ||
|
||||||
|
$connection instanceof \RedisCluster ||
|
||||||
|
$connection instanceof \Predis\Client ||
|
||||||
|
$connection instanceof RedisProxy ||
|
||||||
|
$connection instanceof RedisClusterProxy
|
||||||
|
) {
|
||||||
return new RedisStore($connection);
|
return new RedisStore($connection);
|
||||||
}
|
}
|
||||||
if ($connection instanceof \Memcached) {
|
if ($connection instanceof \Memcached) {
|
||||||
|
Reference in New Issue
Block a user