From 0c28d17fafe33900e122e6d6d7604272d61a331d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 5 Jun 2024 15:50:05 +0200 Subject: [PATCH 01/44] [Cache] Don't use LazyProxyTrait in redis proxies --- Tests/Traits/RedisProxiesTest.php | 18 +- Traits/Redis5Proxy.php | 483 ++++++++++++++------------- Traits/Redis6Proxy.php | 509 +++++++++++++++-------------- Traits/RedisCluster5Proxy.php | 385 +++++++++++----------- Traits/RedisCluster6Proxy.php | 449 +++++++++++++------------ Traits/RedisProxyTrait.php | 48 +++ Traits/RelayProxy.php | 521 +++++++++++++++--------------- 7 files changed, 1223 insertions(+), 1190 deletions(-) create mode 100644 Traits/RedisProxyTrait.php diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index 36f57f09..89c8a378 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -13,7 +13,7 @@ use PHPUnit\Framework\TestCase; use Relay\Relay; -use Symfony\Component\VarExporter\LazyProxyTrait; +use Symfony\Component\Cache\Traits\RedisProxyTrait; use Symfony\Component\VarExporter\ProxyHelper; class RedisProxiesTest extends TestCase @@ -28,17 +28,17 @@ public function testRedisProxy($class) { $version = version_compare(phpversion('redis'), '6', '>') ? '6' : '5'; $proxy = file_get_contents(\dirname(__DIR__, 2)."/Traits/{$class}{$version}Proxy.php"); - $expected = substr($proxy, 0, 4 + strpos($proxy, '[];')); + $expected = substr($proxy, 0, 2 + strpos($proxy, '}')); $methods = []; foreach ((new \ReflectionClass($class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name)) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name)) { continue; } - $return = $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; + $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; $methods[] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args}); + {$return}\$this->initializeLazyObject()->{$method->name}({$args}); } EOPHP; @@ -60,17 +60,17 @@ public function testRedisProxy($class) public function testRelayProxy() { $proxy = file_get_contents(\dirname(__DIR__, 2).'/Traits/RelayProxy.php'); - $proxy = substr($proxy, 0, 4 + strpos($proxy, '[];')); + $proxy = substr($proxy, 0, 2 + strpos($proxy, '}')); $methods = []; foreach ((new \ReflectionClass(Relay::class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { continue; } - $return = $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; + $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; $methods[] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args}); + {$return}\$this->initializeLazyObject()->{$method->name}({$args}); } EOPHP; diff --git a/Traits/Redis5Proxy.php b/Traits/Redis5Proxy.php index 0b2794ee..b2402f25 100644 --- a/Traits/Redis5Proxy.php +++ b/Traits/Redis5Proxy.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\VarExporter\LazyObjectInterface; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Contracts\Service\ResetInterface; // Help opcache.preload discover always-needed symbols @@ -25,1204 +24,1202 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class Redis5Proxy extends \Redis implements ResetInterface, LazyObjectInterface { - use LazyProxyTrait { + use RedisProxyTrait { resetLazyObject as reset; } - private const LAZY_OBJECT_PROPERTY_SCOPES = []; - public function __construct() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->__construct(...\func_get_args()); + $this->initializeLazyObject()->__construct(...\func_get_args()); } public function _prefix($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_prefix(...\func_get_args()); + return $this->initializeLazyObject()->_prefix(...\func_get_args()); } public function _serialize($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_serialize(...\func_get_args()); + return $this->initializeLazyObject()->_serialize(...\func_get_args()); } public function _unserialize($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unserialize(...\func_get_args()); + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); } public function _pack($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_pack(...\func_get_args()); + return $this->initializeLazyObject()->_pack(...\func_get_args()); } public function _unpack($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unpack(...\func_get_args()); + return $this->initializeLazyObject()->_unpack(...\func_get_args()); } public function _compress($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_compress(...\func_get_args()); + return $this->initializeLazyObject()->_compress(...\func_get_args()); } public function _uncompress($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_uncompress(...\func_get_args()); + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); } public function acl($subcmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->acl(...\func_get_args()); + return $this->initializeLazyObject()->acl(...\func_get_args()); } public function append($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->append(...\func_get_args()); + return $this->initializeLazyObject()->append(...\func_get_args()); } public function auth(#[\SensitiveParameter] $auth) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->auth(...\func_get_args()); + return $this->initializeLazyObject()->auth(...\func_get_args()); } public function bgSave() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgSave(...\func_get_args()); + return $this->initializeLazyObject()->bgSave(...\func_get_args()); } public function bgrewriteaof() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgrewriteaof(...\func_get_args()); + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } public function bitcount($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitcount(...\func_get_args()); + return $this->initializeLazyObject()->bitcount(...\func_get_args()); } public function bitop($operation, $ret_key, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitop(...\func_get_args()); + return $this->initializeLazyObject()->bitop(...\func_get_args()); } public function bitpos($key, $bit, $start = null, $end = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitpos(...\func_get_args()); + return $this->initializeLazyObject()->bitpos(...\func_get_args()); } public function blPop($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blPop(...\func_get_args()); + return $this->initializeLazyObject()->blPop(...\func_get_args()); } public function brPop($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brPop(...\func_get_args()); + return $this->initializeLazyObject()->brPop(...\func_get_args()); } public function brpoplpush($src, $dst, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } public function bzPopMax($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzPopMax(...\func_get_args()); + return $this->initializeLazyObject()->bzPopMax(...\func_get_args()); } public function bzPopMin($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzPopMin(...\func_get_args()); + return $this->initializeLazyObject()->bzPopMin(...\func_get_args()); } public function clearLastError() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearLastError(...\func_get_args()); + return $this->initializeLazyObject()->clearLastError(...\func_get_args()); } public function client($cmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->client(...\func_get_args()); + return $this->initializeLazyObject()->client(...\func_get_args()); } public function close() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->close(...\func_get_args()); + return $this->initializeLazyObject()->close(...\func_get_args()); } public function command(...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->command(...\func_get_args()); + return $this->initializeLazyObject()->command(...\func_get_args()); } public function config($cmd, $key, $value = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->config(...\func_get_args()); + return $this->initializeLazyObject()->config(...\func_get_args()); } public function connect($host, $port = null, $timeout = null, $retry_interval = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->connect(...\func_get_args()); + return $this->initializeLazyObject()->connect(...\func_get_args()); } public function dbSize() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dbSize(...\func_get_args()); + return $this->initializeLazyObject()->dbSize(...\func_get_args()); } public function debug($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->debug(...\func_get_args()); + return $this->initializeLazyObject()->debug(...\func_get_args()); } public function decr($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decr(...\func_get_args()); + return $this->initializeLazyObject()->decr(...\func_get_args()); } public function decrBy($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrBy(...\func_get_args()); + return $this->initializeLazyObject()->decrBy(...\func_get_args()); } public function del($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->del(...\func_get_args()); + return $this->initializeLazyObject()->del(...\func_get_args()); } public function discard() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->discard(...\func_get_args()); + return $this->initializeLazyObject()->discard(...\func_get_args()); } public function dump($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dump(...\func_get_args()); + return $this->initializeLazyObject()->dump(...\func_get_args()); } public function echo($msg) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args()); + return $this->initializeLazyObject()->echo(...\func_get_args()); } public function eval($script, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval(...\func_get_args()); + return $this->initializeLazyObject()->eval(...\func_get_args()); } public function evalsha($script_sha, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha(...\func_get_args()); + return $this->initializeLazyObject()->evalsha(...\func_get_args()); } public function exec() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exec(...\func_get_args()); + return $this->initializeLazyObject()->exec(...\func_get_args()); } public function exists($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exists(...\func_get_args()); + return $this->initializeLazyObject()->exists(...\func_get_args()); } public function expire($key, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expire(...\func_get_args()); + return $this->initializeLazyObject()->expire(...\func_get_args()); } public function expireAt($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expireAt(...\func_get_args()); + return $this->initializeLazyObject()->expireAt(...\func_get_args()); } public function flushAll($async = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushAll(...\func_get_args()); + return $this->initializeLazyObject()->flushAll(...\func_get_args()); } public function flushDB($async = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushDB(...\func_get_args()); + return $this->initializeLazyObject()->flushDB(...\func_get_args()); } public function geoadd($key, $lng, $lat, $member, ...$other_triples) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geoadd(...\func_get_args()); + return $this->initializeLazyObject()->geoadd(...\func_get_args()); } public function geodist($key, $src, $dst, $unit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geodist(...\func_get_args()); + return $this->initializeLazyObject()->geodist(...\func_get_args()); } public function geohash($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geohash(...\func_get_args()); + return $this->initializeLazyObject()->geohash(...\func_get_args()); } public function geopos($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geopos(...\func_get_args()); + return $this->initializeLazyObject()->geopos(...\func_get_args()); } public function georadius($key, $lng, $lan, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius(...\func_get_args()); + return $this->initializeLazyObject()->georadius(...\func_get_args()); } public function georadius_ro($key, $lng, $lan, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } public function georadiusbymember($key, $member, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); } public function georadiusbymember_ro($key, $member, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); } public function get($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->get(...\func_get_args()); + return $this->initializeLazyObject()->get(...\func_get_args()); } public function getAuth() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getAuth(...\func_get_args()); + return $this->initializeLazyObject()->getAuth(...\func_get_args()); } public function getBit($key, $offset) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getBit(...\func_get_args()); + return $this->initializeLazyObject()->getBit(...\func_get_args()); } public function getDBNum() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getDBNum(...\func_get_args()); + return $this->initializeLazyObject()->getDBNum(...\func_get_args()); } public function getHost() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getHost(...\func_get_args()); + return $this->initializeLazyObject()->getHost(...\func_get_args()); } public function getLastError() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getLastError(...\func_get_args()); + return $this->initializeLazyObject()->getLastError(...\func_get_args()); } public function getMode() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getMode(...\func_get_args()); + return $this->initializeLazyObject()->getMode(...\func_get_args()); } public function getOption($option) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getOption(...\func_get_args()); + return $this->initializeLazyObject()->getOption(...\func_get_args()); } public function getPersistentID() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPersistentID(...\func_get_args()); + return $this->initializeLazyObject()->getPersistentID(...\func_get_args()); } public function getPort() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPort(...\func_get_args()); + return $this->initializeLazyObject()->getPort(...\func_get_args()); } public function getRange($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getRange(...\func_get_args()); + return $this->initializeLazyObject()->getRange(...\func_get_args()); } public function getReadTimeout() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getReadTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getReadTimeout(...\func_get_args()); } public function getSet($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getSet(...\func_get_args()); + return $this->initializeLazyObject()->getSet(...\func_get_args()); } public function getTimeout() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getTimeout(...\func_get_args()); } public function hDel($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hDel(...\func_get_args()); + return $this->initializeLazyObject()->hDel(...\func_get_args()); } public function hExists($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hExists(...\func_get_args()); + return $this->initializeLazyObject()->hExists(...\func_get_args()); } public function hGet($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hGet(...\func_get_args()); + return $this->initializeLazyObject()->hGet(...\func_get_args()); } public function hGetAll($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hGetAll(...\func_get_args()); + return $this->initializeLazyObject()->hGetAll(...\func_get_args()); } public function hIncrBy($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hIncrBy(...\func_get_args()); + return $this->initializeLazyObject()->hIncrBy(...\func_get_args()); } public function hIncrByFloat($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hIncrByFloat(...\func_get_args()); + return $this->initializeLazyObject()->hIncrByFloat(...\func_get_args()); } public function hKeys($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hKeys(...\func_get_args()); + return $this->initializeLazyObject()->hKeys(...\func_get_args()); } public function hLen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hLen(...\func_get_args()); + return $this->initializeLazyObject()->hLen(...\func_get_args()); } public function hMget($key, $keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hMget(...\func_get_args()); + return $this->initializeLazyObject()->hMget(...\func_get_args()); } public function hMset($key, $pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hMset(...\func_get_args()); + return $this->initializeLazyObject()->hMset(...\func_get_args()); } public function hSet($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hSet(...\func_get_args()); + return $this->initializeLazyObject()->hSet(...\func_get_args()); } public function hSetNx($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hSetNx(...\func_get_args()); + return $this->initializeLazyObject()->hSetNx(...\func_get_args()); } public function hStrLen($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hStrLen(...\func_get_args()); + return $this->initializeLazyObject()->hStrLen(...\func_get_args()); } public function hVals($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hVals(...\func_get_args()); + return $this->initializeLazyObject()->hVals(...\func_get_args()); } public function hscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->hscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function incr($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incr(...\func_get_args()); + return $this->initializeLazyObject()->incr(...\func_get_args()); } public function incrBy($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrBy(...\func_get_args()); + return $this->initializeLazyObject()->incrBy(...\func_get_args()); } public function incrByFloat($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrByFloat(...\func_get_args()); + return $this->initializeLazyObject()->incrByFloat(...\func_get_args()); } public function info($option = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->info(...\func_get_args()); + return $this->initializeLazyObject()->info(...\func_get_args()); } public function isConnected() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->isConnected(...\func_get_args()); + return $this->initializeLazyObject()->isConnected(...\func_get_args()); } public function keys($pattern) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->keys(...\func_get_args()); + return $this->initializeLazyObject()->keys(...\func_get_args()); } public function lInsert($key, $position, $pivot, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lInsert(...\func_get_args()); + return $this->initializeLazyObject()->lInsert(...\func_get_args()); } public function lLen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lLen(...\func_get_args()); + return $this->initializeLazyObject()->lLen(...\func_get_args()); } public function lPop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPop(...\func_get_args()); + return $this->initializeLazyObject()->lPop(...\func_get_args()); } public function lPush($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPush(...\func_get_args()); + return $this->initializeLazyObject()->lPush(...\func_get_args()); } public function lPushx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPushx(...\func_get_args()); + return $this->initializeLazyObject()->lPushx(...\func_get_args()); } public function lSet($key, $index, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lSet(...\func_get_args()); + return $this->initializeLazyObject()->lSet(...\func_get_args()); } public function lastSave() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lastSave(...\func_get_args()); + return $this->initializeLazyObject()->lastSave(...\func_get_args()); } public function lindex($key, $index) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lindex(...\func_get_args()); + return $this->initializeLazyObject()->lindex(...\func_get_args()); } public function lrange($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrange(...\func_get_args()); + return $this->initializeLazyObject()->lrange(...\func_get_args()); } public function lrem($key, $value, $count) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrem(...\func_get_args()); + return $this->initializeLazyObject()->lrem(...\func_get_args()); } public function ltrim($key, $start, $stop) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ltrim(...\func_get_args()); + return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public function mget($keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mget(...\func_get_args()); + return $this->initializeLazyObject()->mget(...\func_get_args()); } public function migrate($host, $port, $key, $db, $timeout, $copy = null, $replace = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->migrate(...\func_get_args()); + return $this->initializeLazyObject()->migrate(...\func_get_args()); } public function move($key, $dbindex) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->move(...\func_get_args()); + return $this->initializeLazyObject()->move(...\func_get_args()); } public function mset($pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mset(...\func_get_args()); + return $this->initializeLazyObject()->mset(...\func_get_args()); } public function msetnx($pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->msetnx(...\func_get_args()); + return $this->initializeLazyObject()->msetnx(...\func_get_args()); } public function multi($mode = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->multi(...\func_get_args()); + return $this->initializeLazyObject()->multi(...\func_get_args()); } public function object($field, $key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->object(...\func_get_args()); + return $this->initializeLazyObject()->object(...\func_get_args()); } public function pconnect($host, $port = null, $timeout = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pconnect(...\func_get_args()); + return $this->initializeLazyObject()->pconnect(...\func_get_args()); } public function persist($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->persist(...\func_get_args()); + return $this->initializeLazyObject()->persist(...\func_get_args()); } public function pexpire($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpire(...\func_get_args()); + return $this->initializeLazyObject()->pexpire(...\func_get_args()); } public function pexpireAt($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpireAt(...\func_get_args()); + return $this->initializeLazyObject()->pexpireAt(...\func_get_args()); } public function pfadd($key, $elements) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfadd(...\func_get_args()); + return $this->initializeLazyObject()->pfadd(...\func_get_args()); } public function pfcount($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfcount(...\func_get_args()); + return $this->initializeLazyObject()->pfcount(...\func_get_args()); } public function pfmerge($dstkey, $keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfmerge(...\func_get_args()); + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } public function ping() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ping(...\func_get_args()); + return $this->initializeLazyObject()->ping(...\func_get_args()); } public function pipeline() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pipeline(...\func_get_args()); + return $this->initializeLazyObject()->pipeline(...\func_get_args()); } public function psetex($key, $expire, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psetex(...\func_get_args()); + return $this->initializeLazyObject()->psetex(...\func_get_args()); } public function psubscribe($patterns, $callback) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psubscribe(...\func_get_args()); + return $this->initializeLazyObject()->psubscribe(...\func_get_args()); } public function pttl($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pttl(...\func_get_args()); + return $this->initializeLazyObject()->pttl(...\func_get_args()); } public function publish($channel, $message) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->publish(...\func_get_args()); + return $this->initializeLazyObject()->publish(...\func_get_args()); } public function pubsub($cmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pubsub(...\func_get_args()); + return $this->initializeLazyObject()->pubsub(...\func_get_args()); } public function punsubscribe($pattern, ...$other_patterns) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->punsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); } public function rPop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPop(...\func_get_args()); + return $this->initializeLazyObject()->rPop(...\func_get_args()); } public function rPush($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPush(...\func_get_args()); + return $this->initializeLazyObject()->rPush(...\func_get_args()); } public function rPushx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPushx(...\func_get_args()); + return $this->initializeLazyObject()->rPushx(...\func_get_args()); } public function randomKey() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->randomKey(...\func_get_args()); + return $this->initializeLazyObject()->randomKey(...\func_get_args()); } public function rawcommand($cmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rawcommand(...\func_get_args()); + return $this->initializeLazyObject()->rawcommand(...\func_get_args()); } public function rename($key, $newkey) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rename(...\func_get_args()); + return $this->initializeLazyObject()->rename(...\func_get_args()); } public function renameNx($key, $newkey) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renameNx(...\func_get_args()); + return $this->initializeLazyObject()->renameNx(...\func_get_args()); } public function restore($ttl, $key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->restore(...\func_get_args()); + return $this->initializeLazyObject()->restore(...\func_get_args()); } public function role() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->role(...\func_get_args()); + return $this->initializeLazyObject()->role(...\func_get_args()); } public function rpoplpush($src, $dst) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); } public function sAdd($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sAdd(...\func_get_args()); + return $this->initializeLazyObject()->sAdd(...\func_get_args()); } public function sAddArray($key, $options) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sAddArray(...\func_get_args()); + return $this->initializeLazyObject()->sAddArray(...\func_get_args()); } public function sDiff($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sDiff(...\func_get_args()); + return $this->initializeLazyObject()->sDiff(...\func_get_args()); } public function sDiffStore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sDiffStore(...\func_get_args()); + return $this->initializeLazyObject()->sDiffStore(...\func_get_args()); } public function sInter($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sInter(...\func_get_args()); + return $this->initializeLazyObject()->sInter(...\func_get_args()); } public function sInterStore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sInterStore(...\func_get_args()); + return $this->initializeLazyObject()->sInterStore(...\func_get_args()); } public function sMembers($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMembers(...\func_get_args()); + return $this->initializeLazyObject()->sMembers(...\func_get_args()); } public function sMisMember($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMisMember(...\func_get_args()); + return $this->initializeLazyObject()->sMisMember(...\func_get_args()); } public function sMove($src, $dst, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMove(...\func_get_args()); + return $this->initializeLazyObject()->sMove(...\func_get_args()); } public function sPop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sPop(...\func_get_args()); + return $this->initializeLazyObject()->sPop(...\func_get_args()); } public function sRandMember($key, $count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sRandMember(...\func_get_args()); + return $this->initializeLazyObject()->sRandMember(...\func_get_args()); } public function sUnion($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sUnion(...\func_get_args()); + return $this->initializeLazyObject()->sUnion(...\func_get_args()); } public function sUnionStore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sUnionStore(...\func_get_args()); + return $this->initializeLazyObject()->sUnionStore(...\func_get_args()); } public function save() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->save(...\func_get_args()); + return $this->initializeLazyObject()->save(...\func_get_args()); } public function scan(&$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scan($i_iterator, ...\array_slice(\func_get_args(), 1)); + return $this->initializeLazyObject()->scan($i_iterator, ...\array_slice(\func_get_args(), 1)); } public function scard($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scard(...\func_get_args()); + return $this->initializeLazyObject()->scard(...\func_get_args()); } public function script($cmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->script(...\func_get_args()); + return $this->initializeLazyObject()->script(...\func_get_args()); } public function select($dbindex) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->select(...\func_get_args()); + return $this->initializeLazyObject()->select(...\func_get_args()); } public function set($key, $value, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->set(...\func_get_args()); + return $this->initializeLazyObject()->set(...\func_get_args()); } public function setBit($key, $offset, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setBit(...\func_get_args()); + return $this->initializeLazyObject()->setBit(...\func_get_args()); } public function setOption($option, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setOption(...\func_get_args()); + return $this->initializeLazyObject()->setOption(...\func_get_args()); } public function setRange($key, $offset, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setRange(...\func_get_args()); + return $this->initializeLazyObject()->setRange(...\func_get_args()); } public function setex($key, $expire, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setex(...\func_get_args()); + return $this->initializeLazyObject()->setex(...\func_get_args()); } public function setnx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setnx(...\func_get_args()); + return $this->initializeLazyObject()->setnx(...\func_get_args()); } public function sismember($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sismember(...\func_get_args()); + return $this->initializeLazyObject()->sismember(...\func_get_args()); } public function slaveof($host = null, $port = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slaveof(...\func_get_args()); + return $this->initializeLazyObject()->slaveof(...\func_get_args()); } public function slowlog($arg, $option = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slowlog(...\func_get_args()); + return $this->initializeLazyObject()->slowlog(...\func_get_args()); } public function sort($key, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort(...\func_get_args()); + return $this->initializeLazyObject()->sort(...\func_get_args()); } public function sortAsc($key, $pattern = null, $get = null, $start = null, $end = null, $getList = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortAsc(...\func_get_args()); + return $this->initializeLazyObject()->sortAsc(...\func_get_args()); } public function sortAscAlpha($key, $pattern = null, $get = null, $start = null, $end = null, $getList = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortAscAlpha(...\func_get_args()); + return $this->initializeLazyObject()->sortAscAlpha(...\func_get_args()); } public function sortDesc($key, $pattern = null, $get = null, $start = null, $end = null, $getList = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortDesc(...\func_get_args()); + return $this->initializeLazyObject()->sortDesc(...\func_get_args()); } public function sortDescAlpha($key, $pattern = null, $get = null, $start = null, $end = null, $getList = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortDescAlpha(...\func_get_args()); + return $this->initializeLazyObject()->sortDescAlpha(...\func_get_args()); } public function srem($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srem(...\func_get_args()); + return $this->initializeLazyObject()->srem(...\func_get_args()); } public function sscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->sscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function strlen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->strlen(...\func_get_args()); + return $this->initializeLazyObject()->strlen(...\func_get_args()); } public function subscribe($channels, $callback) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->subscribe(...\func_get_args()); + return $this->initializeLazyObject()->subscribe(...\func_get_args()); } public function swapdb($srcdb, $dstdb) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->swapdb(...\func_get_args()); + return $this->initializeLazyObject()->swapdb(...\func_get_args()); } public function time() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->time(...\func_get_args()); + return $this->initializeLazyObject()->time(...\func_get_args()); } public function ttl($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ttl(...\func_get_args()); + return $this->initializeLazyObject()->ttl(...\func_get_args()); } public function type($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->type(...\func_get_args()); + return $this->initializeLazyObject()->type(...\func_get_args()); } public function unlink($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unlink(...\func_get_args()); + return $this->initializeLazyObject()->unlink(...\func_get_args()); } public function unsubscribe($channel, ...$other_channels) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); } public function unwatch() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unwatch(...\func_get_args()); + return $this->initializeLazyObject()->unwatch(...\func_get_args()); } public function wait($numslaves, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->wait(...\func_get_args()); + return $this->initializeLazyObject()->wait(...\func_get_args()); } public function watch($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->watch(...\func_get_args()); + return $this->initializeLazyObject()->watch(...\func_get_args()); } public function xack($str_key, $str_group, $arr_ids) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xack(...\func_get_args()); + return $this->initializeLazyObject()->xack(...\func_get_args()); } public function xadd($str_key, $str_id, $arr_fields, $i_maxlen = null, $boo_approximate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xadd(...\func_get_args()); + return $this->initializeLazyObject()->xadd(...\func_get_args()); } public function xclaim($str_key, $str_group, $str_consumer, $i_min_idle, $arr_ids, $arr_opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xclaim(...\func_get_args()); + return $this->initializeLazyObject()->xclaim(...\func_get_args()); } public function xdel($str_key, $arr_ids) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xdel(...\func_get_args()); + return $this->initializeLazyObject()->xdel(...\func_get_args()); } public function xgroup($str_operation, $str_key = null, $str_arg1 = null, $str_arg2 = null, $str_arg3 = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xgroup(...\func_get_args()); + return $this->initializeLazyObject()->xgroup(...\func_get_args()); } public function xinfo($str_cmd, $str_key = null, $str_group = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xinfo(...\func_get_args()); + return $this->initializeLazyObject()->xinfo(...\func_get_args()); } public function xlen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xlen(...\func_get_args()); + return $this->initializeLazyObject()->xlen(...\func_get_args()); } public function xpending($str_key, $str_group, $str_start = null, $str_end = null, $i_count = null, $str_consumer = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xpending(...\func_get_args()); + return $this->initializeLazyObject()->xpending(...\func_get_args()); } public function xrange($str_key, $str_start, $str_end, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrange(...\func_get_args()); + return $this->initializeLazyObject()->xrange(...\func_get_args()); } public function xread($arr_streams, $i_count = null, $i_block = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xread(...\func_get_args()); + return $this->initializeLazyObject()->xread(...\func_get_args()); } public function xreadgroup($str_group, $str_consumer, $arr_streams, $i_count = null, $i_block = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xreadgroup(...\func_get_args()); + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } public function xrevrange($str_key, $str_start, $str_end, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrevrange(...\func_get_args()); + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } public function xtrim($str_key, $i_maxlen, $boo_approximate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xtrim(...\func_get_args()); + return $this->initializeLazyObject()->xtrim(...\func_get_args()); } public function zAdd($key, $score, $value, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zAdd(...\func_get_args()); + return $this->initializeLazyObject()->zAdd(...\func_get_args()); } public function zCard($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zCard(...\func_get_args()); + return $this->initializeLazyObject()->zCard(...\func_get_args()); } public function zCount($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zCount(...\func_get_args()); + return $this->initializeLazyObject()->zCount(...\func_get_args()); } public function zIncrBy($key, $value, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zIncrBy(...\func_get_args()); + return $this->initializeLazyObject()->zIncrBy(...\func_get_args()); } public function zLexCount($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zLexCount(...\func_get_args()); + return $this->initializeLazyObject()->zLexCount(...\func_get_args()); } public function zPopMax($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zPopMax(...\func_get_args()); + return $this->initializeLazyObject()->zPopMax(...\func_get_args()); } public function zPopMin($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zPopMin(...\func_get_args()); + return $this->initializeLazyObject()->zPopMin(...\func_get_args()); } public function zRange($key, $start, $end, $scores = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRange(...\func_get_args()); + return $this->initializeLazyObject()->zRange(...\func_get_args()); } public function zRangeByLex($key, $min, $max, $offset = null, $limit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRangeByLex(...\func_get_args()); } public function zRangeByScore($key, $start, $end, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRangeByScore(...\func_get_args()); } public function zRank($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRank(...\func_get_args()); + return $this->initializeLazyObject()->zRank(...\func_get_args()); } public function zRem($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRem(...\func_get_args()); + return $this->initializeLazyObject()->zRem(...\func_get_args()); } public function zRemRangeByLex($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByLex(...\func_get_args()); } public function zRemRangeByRank($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByRank(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByRank(...\func_get_args()); } public function zRemRangeByScore($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByScore(...\func_get_args()); } public function zRevRange($key, $start, $end, $scores = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRange(...\func_get_args()); + return $this->initializeLazyObject()->zRevRange(...\func_get_args()); } public function zRevRangeByLex($key, $min, $max, $offset = null, $limit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRevRangeByLex(...\func_get_args()); } public function zRevRangeByScore($key, $start, $end, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRevRangeByScore(...\func_get_args()); } public function zRevRank($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRank(...\func_get_args()); + return $this->initializeLazyObject()->zRevRank(...\func_get_args()); } public function zScore($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zScore(...\func_get_args()); + return $this->initializeLazyObject()->zScore(...\func_get_args()); } public function zinterstore($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinterstore(...\func_get_args()); + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } public function zscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->zscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function zunionstore($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunionstore(...\func_get_args()); + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } public function delete($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->delete(...\func_get_args()); + return $this->initializeLazyObject()->delete(...\func_get_args()); } public function evaluate($script, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evaluate(...\func_get_args()); + return $this->initializeLazyObject()->evaluate(...\func_get_args()); } public function evaluateSha($script_sha, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evaluateSha(...\func_get_args()); + return $this->initializeLazyObject()->evaluateSha(...\func_get_args()); } public function getKeys($pattern) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getKeys(...\func_get_args()); + return $this->initializeLazyObject()->getKeys(...\func_get_args()); } public function getMultiple($keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getMultiple(...\func_get_args()); + return $this->initializeLazyObject()->getMultiple(...\func_get_args()); } public function lGet($key, $index) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lGet(...\func_get_args()); + return $this->initializeLazyObject()->lGet(...\func_get_args()); } public function lGetRange($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lGetRange(...\func_get_args()); + return $this->initializeLazyObject()->lGetRange(...\func_get_args()); } public function lRemove($key, $value, $count) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lRemove(...\func_get_args()); + return $this->initializeLazyObject()->lRemove(...\func_get_args()); } public function lSize($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lSize(...\func_get_args()); + return $this->initializeLazyObject()->lSize(...\func_get_args()); } public function listTrim($key, $start, $stop) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->listTrim(...\func_get_args()); + return $this->initializeLazyObject()->listTrim(...\func_get_args()); } public function open($host, $port = null, $timeout = null, $retry_interval = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->open(...\func_get_args()); + return $this->initializeLazyObject()->open(...\func_get_args()); } public function popen($host, $port = null, $timeout = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->popen(...\func_get_args()); + return $this->initializeLazyObject()->popen(...\func_get_args()); } public function renameKey($key, $newkey) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renameKey(...\func_get_args()); + return $this->initializeLazyObject()->renameKey(...\func_get_args()); } public function sContains($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sContains(...\func_get_args()); + return $this->initializeLazyObject()->sContains(...\func_get_args()); } public function sGetMembers($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sGetMembers(...\func_get_args()); + return $this->initializeLazyObject()->sGetMembers(...\func_get_args()); } public function sRemove($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sRemove(...\func_get_args()); + return $this->initializeLazyObject()->sRemove(...\func_get_args()); } public function sSize($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sSize(...\func_get_args()); + return $this->initializeLazyObject()->sSize(...\func_get_args()); } public function sendEcho($msg) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sendEcho(...\func_get_args()); + return $this->initializeLazyObject()->sendEcho(...\func_get_args()); } public function setTimeout($key, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setTimeout(...\func_get_args()); + return $this->initializeLazyObject()->setTimeout(...\func_get_args()); } public function substr($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->substr(...\func_get_args()); + return $this->initializeLazyObject()->substr(...\func_get_args()); } public function zDelete($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zDelete(...\func_get_args()); + return $this->initializeLazyObject()->zDelete(...\func_get_args()); } public function zDeleteRangeByRank($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zDeleteRangeByRank(...\func_get_args()); + return $this->initializeLazyObject()->zDeleteRangeByRank(...\func_get_args()); } public function zDeleteRangeByScore($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zDeleteRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zDeleteRangeByScore(...\func_get_args()); } public function zInter($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zInter(...\func_get_args()); + return $this->initializeLazyObject()->zInter(...\func_get_args()); } public function zRemove($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemove(...\func_get_args()); + return $this->initializeLazyObject()->zRemove(...\func_get_args()); } public function zRemoveRangeByScore($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemoveRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRemoveRangeByScore(...\func_get_args()); } public function zReverseRange($key, $start, $end, $scores = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zReverseRange(...\func_get_args()); + return $this->initializeLazyObject()->zReverseRange(...\func_get_args()); } public function zSize($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zSize(...\func_get_args()); + return $this->initializeLazyObject()->zSize(...\func_get_args()); } public function zUnion($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zUnion(...\func_get_args()); + return $this->initializeLazyObject()->zUnion(...\func_get_args()); } } diff --git a/Traits/Redis6Proxy.php b/Traits/Redis6Proxy.php index 0680404f..81449492 100644 --- a/Traits/Redis6Proxy.php +++ b/Traits/Redis6Proxy.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\VarExporter\LazyObjectInterface; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Contracts\Service\ResetInterface; // Help opcache.preload discover always-needed symbols @@ -25,1269 +24,1267 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class Redis6Proxy extends \Redis implements ResetInterface, LazyObjectInterface { - use LazyProxyTrait { + use RedisProxyTrait { resetLazyObject as reset; } - private const LAZY_OBJECT_PROPERTY_SCOPES = []; - public function __construct($options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->__construct(...\func_get_args()); + $this->initializeLazyObject()->__construct(...\func_get_args()); } public function _compress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_compress(...\func_get_args()); + return $this->initializeLazyObject()->_compress(...\func_get_args()); } public function _uncompress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_uncompress(...\func_get_args()); + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); } public function _prefix($key): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_prefix(...\func_get_args()); + return $this->initializeLazyObject()->_prefix(...\func_get_args()); } public function _serialize($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_serialize(...\func_get_args()); + return $this->initializeLazyObject()->_serialize(...\func_get_args()); } public function _unserialize($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unserialize(...\func_get_args()); + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); } public function _pack($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_pack(...\func_get_args()); + return $this->initializeLazyObject()->_pack(...\func_get_args()); } public function _unpack($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unpack(...\func_get_args()); + return $this->initializeLazyObject()->_unpack(...\func_get_args()); } public function acl($subcmd, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->acl(...\func_get_args()); + return $this->initializeLazyObject()->acl(...\func_get_args()); } public function append($key, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->append(...\func_get_args()); + return $this->initializeLazyObject()->append(...\func_get_args()); } public function auth(#[\SensitiveParameter] $credentials): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->auth(...\func_get_args()); + return $this->initializeLazyObject()->auth(...\func_get_args()); } public function bgSave(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgSave(...\func_get_args()); + return $this->initializeLazyObject()->bgSave(...\func_get_args()); } public function bgrewriteaof(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgrewriteaof(...\func_get_args()); + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } public function bitcount($key, $start = 0, $end = -1, $bybit = false): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitcount(...\func_get_args()); + return $this->initializeLazyObject()->bitcount(...\func_get_args()); } public function bitop($operation, $deskey, $srckey, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitop(...\func_get_args()); + return $this->initializeLazyObject()->bitop(...\func_get_args()); } public function bitpos($key, $bit, $start = 0, $end = -1, $bybit = false): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitpos(...\func_get_args()); + return $this->initializeLazyObject()->bitpos(...\func_get_args()); } public function blPop($key_or_keys, $timeout_or_key, ...$extra_args): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blPop(...\func_get_args()); + return $this->initializeLazyObject()->blPop(...\func_get_args()); } public function brPop($key_or_keys, $timeout_or_key, ...$extra_args): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brPop(...\func_get_args()); + return $this->initializeLazyObject()->brPop(...\func_get_args()); } public function brpoplpush($src, $dst, $timeout): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } public function bzPopMax($key, $timeout_or_key, ...$extra_args): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzPopMax(...\func_get_args()); + return $this->initializeLazyObject()->bzPopMax(...\func_get_args()); } public function bzPopMin($key, $timeout_or_key, ...$extra_args): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzPopMin(...\func_get_args()); + return $this->initializeLazyObject()->bzPopMin(...\func_get_args()); } public function bzmpop($timeout, $keys, $from, $count = 1): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzmpop(...\func_get_args()); + return $this->initializeLazyObject()->bzmpop(...\func_get_args()); } public function zmpop($keys, $from, $count = 1): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zmpop(...\func_get_args()); + return $this->initializeLazyObject()->zmpop(...\func_get_args()); } public function blmpop($timeout, $keys, $from, $count = 1): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmpop(...\func_get_args()); + return $this->initializeLazyObject()->blmpop(...\func_get_args()); } public function lmpop($keys, $from, $count = 1): \Redis|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lmpop(...\func_get_args()); + return $this->initializeLazyObject()->lmpop(...\func_get_args()); } public function clearLastError(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearLastError(...\func_get_args()); + return $this->initializeLazyObject()->clearLastError(...\func_get_args()); } public function client($opt, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->client(...\func_get_args()); + return $this->initializeLazyObject()->client(...\func_get_args()); } public function close(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->close(...\func_get_args()); + return $this->initializeLazyObject()->close(...\func_get_args()); } public function command($opt = null, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->command(...\func_get_args()); + return $this->initializeLazyObject()->command(...\func_get_args()); } public function config($operation, $key_or_settings = null, $value = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->config(...\func_get_args()); + return $this->initializeLazyObject()->config(...\func_get_args()); } public function connect($host, $port = 6379, $timeout = 0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0, $context = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->connect(...\func_get_args()); + return $this->initializeLazyObject()->connect(...\func_get_args()); } public function copy($src, $dst, $options = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args()); + return $this->initializeLazyObject()->copy(...\func_get_args()); } public function dbSize(): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dbSize(...\func_get_args()); + return $this->initializeLazyObject()->dbSize(...\func_get_args()); } public function debug($key): \Redis|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->debug(...\func_get_args()); + return $this->initializeLazyObject()->debug(...\func_get_args()); } public function decr($key, $by = 1): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decr(...\func_get_args()); + return $this->initializeLazyObject()->decr(...\func_get_args()); } public function decrBy($key, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrBy(...\func_get_args()); + return $this->initializeLazyObject()->decrBy(...\func_get_args()); } public function del($key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->del(...\func_get_args()); + return $this->initializeLazyObject()->del(...\func_get_args()); } public function delete($key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->delete(...\func_get_args()); + return $this->initializeLazyObject()->delete(...\func_get_args()); } public function discard(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->discard(...\func_get_args()); + return $this->initializeLazyObject()->discard(...\func_get_args()); } public function dump($key): \Redis|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dump(...\func_get_args()); + return $this->initializeLazyObject()->dump(...\func_get_args()); } public function echo($str): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args()); + return $this->initializeLazyObject()->echo(...\func_get_args()); } public function eval($script, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval(...\func_get_args()); + return $this->initializeLazyObject()->eval(...\func_get_args()); } public function eval_ro($script_sha, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval_ro(...\func_get_args()); + return $this->initializeLazyObject()->eval_ro(...\func_get_args()); } public function evalsha($sha1, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha(...\func_get_args()); + return $this->initializeLazyObject()->evalsha(...\func_get_args()); } public function evalsha_ro($sha1, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha_ro(...\func_get_args()); + return $this->initializeLazyObject()->evalsha_ro(...\func_get_args()); } public function exec(): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exec(...\func_get_args()); + return $this->initializeLazyObject()->exec(...\func_get_args()); } public function exists($key, ...$other_keys): \Redis|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exists(...\func_get_args()); + return $this->initializeLazyObject()->exists(...\func_get_args()); } public function expire($key, $timeout, $mode = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expire(...\func_get_args()); + return $this->initializeLazyObject()->expire(...\func_get_args()); } public function expireAt($key, $timestamp, $mode = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expireAt(...\func_get_args()); + return $this->initializeLazyObject()->expireAt(...\func_get_args()); } public function failover($to = null, $abort = false, $timeout = 0): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->failover(...\func_get_args()); + return $this->initializeLazyObject()->failover(...\func_get_args()); } public function expiretime($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expiretime(...\func_get_args()); + return $this->initializeLazyObject()->expiretime(...\func_get_args()); } public function pexpiretime($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpiretime(...\func_get_args()); + return $this->initializeLazyObject()->pexpiretime(...\func_get_args()); } public function fcall($fn, $keys = [], $args = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->fcall(...\func_get_args()); + return $this->initializeLazyObject()->fcall(...\func_get_args()); } public function fcall_ro($fn, $keys = [], $args = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->fcall_ro(...\func_get_args()); + return $this->initializeLazyObject()->fcall_ro(...\func_get_args()); } public function flushAll($sync = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushAll(...\func_get_args()); + return $this->initializeLazyObject()->flushAll(...\func_get_args()); } public function flushDB($sync = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushDB(...\func_get_args()); + return $this->initializeLazyObject()->flushDB(...\func_get_args()); } public function function($operation, ...$args): \Redis|array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->function(...\func_get_args()); + return $this->initializeLazyObject()->function(...\func_get_args()); } public function geoadd($key, $lng, $lat, $member, ...$other_triples_and_options): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geoadd(...\func_get_args()); + return $this->initializeLazyObject()->geoadd(...\func_get_args()); } public function geodist($key, $src, $dst, $unit = null): \Redis|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geodist(...\func_get_args()); + return $this->initializeLazyObject()->geodist(...\func_get_args()); } public function geohash($key, $member, ...$other_members): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geohash(...\func_get_args()); + return $this->initializeLazyObject()->geohash(...\func_get_args()); } public function geopos($key, $member, ...$other_members): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geopos(...\func_get_args()); + return $this->initializeLazyObject()->geopos(...\func_get_args()); } public function georadius($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius(...\func_get_args()); + return $this->initializeLazyObject()->georadius(...\func_get_args()); } public function georadius_ro($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } public function georadiusbymember($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); } public function georadiusbymember_ro($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); } public function geosearch($key, $position, $shape, $unit, $options = []): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearch(...\func_get_args()); + return $this->initializeLazyObject()->geosearch(...\func_get_args()); } public function geosearchstore($dst, $src, $position, $shape, $unit, $options = []): \Redis|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearchstore(...\func_get_args()); + return $this->initializeLazyObject()->geosearchstore(...\func_get_args()); } public function get($key): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->get(...\func_get_args()); + return $this->initializeLazyObject()->get(...\func_get_args()); } public function getAuth(): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getAuth(...\func_get_args()); + return $this->initializeLazyObject()->getAuth(...\func_get_args()); } public function getBit($key, $idx): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getBit(...\func_get_args()); + return $this->initializeLazyObject()->getBit(...\func_get_args()); } public function getEx($key, $options = []): \Redis|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getEx(...\func_get_args()); + return $this->initializeLazyObject()->getEx(...\func_get_args()); } public function getDBNum(): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getDBNum(...\func_get_args()); + return $this->initializeLazyObject()->getDBNum(...\func_get_args()); } public function getDel($key): \Redis|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getDel(...\func_get_args()); + return $this->initializeLazyObject()->getDel(...\func_get_args()); } public function getHost(): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getHost(...\func_get_args()); + return $this->initializeLazyObject()->getHost(...\func_get_args()); } public function getLastError(): ?string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getLastError(...\func_get_args()); + return $this->initializeLazyObject()->getLastError(...\func_get_args()); } public function getMode(): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getMode(...\func_get_args()); + return $this->initializeLazyObject()->getMode(...\func_get_args()); } public function getOption($option): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getOption(...\func_get_args()); + return $this->initializeLazyObject()->getOption(...\func_get_args()); } public function getPersistentID(): ?string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPersistentID(...\func_get_args()); + return $this->initializeLazyObject()->getPersistentID(...\func_get_args()); } public function getPort(): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPort(...\func_get_args()); + return $this->initializeLazyObject()->getPort(...\func_get_args()); } public function getRange($key, $start, $end): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getRange(...\func_get_args()); + return $this->initializeLazyObject()->getRange(...\func_get_args()); } public function lcs($key1, $key2, $options = null): \Redis|array|false|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lcs(...\func_get_args()); + return $this->initializeLazyObject()->lcs(...\func_get_args()); } public function getReadTimeout(): float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getReadTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getReadTimeout(...\func_get_args()); } public function getset($key, $value): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getset(...\func_get_args()); + return $this->initializeLazyObject()->getset(...\func_get_args()); } public function getTimeout(): false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getTimeout(...\func_get_args()); } public function getTransferredBytes(): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getTransferredBytes(...\func_get_args()); + return $this->initializeLazyObject()->getTransferredBytes(...\func_get_args()); } public function clearTransferredBytes(): void { - ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearTransferredBytes(...\func_get_args()); + $this->initializeLazyObject()->clearTransferredBytes(...\func_get_args()); } public function hDel($key, $field, ...$other_fields): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hDel(...\func_get_args()); + return $this->initializeLazyObject()->hDel(...\func_get_args()); } public function hExists($key, $field): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hExists(...\func_get_args()); + return $this->initializeLazyObject()->hExists(...\func_get_args()); } public function hGet($key, $member): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hGet(...\func_get_args()); + return $this->initializeLazyObject()->hGet(...\func_get_args()); } public function hGetAll($key): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hGetAll(...\func_get_args()); + return $this->initializeLazyObject()->hGetAll(...\func_get_args()); } public function hIncrBy($key, $field, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hIncrBy(...\func_get_args()); + return $this->initializeLazyObject()->hIncrBy(...\func_get_args()); } public function hIncrByFloat($key, $field, $value): \Redis|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hIncrByFloat(...\func_get_args()); + return $this->initializeLazyObject()->hIncrByFloat(...\func_get_args()); } public function hKeys($key): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hKeys(...\func_get_args()); + return $this->initializeLazyObject()->hKeys(...\func_get_args()); } public function hLen($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hLen(...\func_get_args()); + return $this->initializeLazyObject()->hLen(...\func_get_args()); } public function hMget($key, $fields): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hMget(...\func_get_args()); + return $this->initializeLazyObject()->hMget(...\func_get_args()); } public function hMset($key, $fieldvals): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hMset(...\func_get_args()); + return $this->initializeLazyObject()->hMset(...\func_get_args()); } public function hRandField($key, $options = null): \Redis|array|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hRandField(...\func_get_args()); + return $this->initializeLazyObject()->hRandField(...\func_get_args()); } public function hSet($key, $member, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hSet(...\func_get_args()); + return $this->initializeLazyObject()->hSet(...\func_get_args()); } public function hSetNx($key, $field, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hSetNx(...\func_get_args()); + return $this->initializeLazyObject()->hSetNx(...\func_get_args()); } public function hStrLen($key, $field): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hStrLen(...\func_get_args()); + return $this->initializeLazyObject()->hStrLen(...\func_get_args()); } public function hVals($key): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hVals(...\func_get_args()); + return $this->initializeLazyObject()->hVals(...\func_get_args()); } public function hscan($key, &$iterator, $pattern = null, $count = 0): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function incr($key, $by = 1): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incr(...\func_get_args()); + return $this->initializeLazyObject()->incr(...\func_get_args()); } public function incrBy($key, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrBy(...\func_get_args()); + return $this->initializeLazyObject()->incrBy(...\func_get_args()); } public function incrByFloat($key, $value): \Redis|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrByFloat(...\func_get_args()); + return $this->initializeLazyObject()->incrByFloat(...\func_get_args()); } public function info(...$sections): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->info(...\func_get_args()); + return $this->initializeLazyObject()->info(...\func_get_args()); } public function isConnected(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->isConnected(...\func_get_args()); + return $this->initializeLazyObject()->isConnected(...\func_get_args()); } public function keys($pattern) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->keys(...\func_get_args()); + return $this->initializeLazyObject()->keys(...\func_get_args()); } public function lInsert($key, $pos, $pivot, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lInsert(...\func_get_args()); + return $this->initializeLazyObject()->lInsert(...\func_get_args()); } public function lLen($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lLen(...\func_get_args()); + return $this->initializeLazyObject()->lLen(...\func_get_args()); } public function lMove($src, $dst, $wherefrom, $whereto): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lMove(...\func_get_args()); + return $this->initializeLazyObject()->lMove(...\func_get_args()); } public function blmove($src, $dst, $wherefrom, $whereto, $timeout): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmove(...\func_get_args()); + return $this->initializeLazyObject()->blmove(...\func_get_args()); } public function lPop($key, $count = 0): \Redis|array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPop(...\func_get_args()); + return $this->initializeLazyObject()->lPop(...\func_get_args()); } public function lPos($key, $value, $options = null): \Redis|array|bool|int|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPos(...\func_get_args()); + return $this->initializeLazyObject()->lPos(...\func_get_args()); } public function lPush($key, ...$elements): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPush(...\func_get_args()); + return $this->initializeLazyObject()->lPush(...\func_get_args()); } public function rPush($key, ...$elements): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPush(...\func_get_args()); + return $this->initializeLazyObject()->rPush(...\func_get_args()); } public function lPushx($key, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lPushx(...\func_get_args()); + return $this->initializeLazyObject()->lPushx(...\func_get_args()); } public function rPushx($key, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPushx(...\func_get_args()); + return $this->initializeLazyObject()->rPushx(...\func_get_args()); } public function lSet($key, $index, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lSet(...\func_get_args()); + return $this->initializeLazyObject()->lSet(...\func_get_args()); } public function lastSave(): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lastSave(...\func_get_args()); + return $this->initializeLazyObject()->lastSave(...\func_get_args()); } public function lindex($key, $index): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lindex(...\func_get_args()); + return $this->initializeLazyObject()->lindex(...\func_get_args()); } public function lrange($key, $start, $end): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrange(...\func_get_args()); + return $this->initializeLazyObject()->lrange(...\func_get_args()); } public function lrem($key, $value, $count = 0): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrem(...\func_get_args()); + return $this->initializeLazyObject()->lrem(...\func_get_args()); } public function ltrim($key, $start, $end): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ltrim(...\func_get_args()); + return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public function mget($keys): \Redis|array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mget(...\func_get_args()); + return $this->initializeLazyObject()->mget(...\func_get_args()); } public function migrate($host, $port, $key, $dstdb, $timeout, $copy = false, $replace = false, #[\SensitiveParameter] $credentials = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->migrate(...\func_get_args()); + return $this->initializeLazyObject()->migrate(...\func_get_args()); } public function move($key, $index): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->move(...\func_get_args()); + return $this->initializeLazyObject()->move(...\func_get_args()); } public function mset($key_values): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mset(...\func_get_args()); + return $this->initializeLazyObject()->mset(...\func_get_args()); } public function msetnx($key_values): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->msetnx(...\func_get_args()); + return $this->initializeLazyObject()->msetnx(...\func_get_args()); } public function multi($value = \Redis::MULTI): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->multi(...\func_get_args()); + return $this->initializeLazyObject()->multi(...\func_get_args()); } public function object($subcommand, $key): \Redis|false|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->object(...\func_get_args()); + return $this->initializeLazyObject()->object(...\func_get_args()); } public function open($host, $port = 6379, $timeout = 0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0, $context = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->open(...\func_get_args()); + return $this->initializeLazyObject()->open(...\func_get_args()); } public function pconnect($host, $port = 6379, $timeout = 0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0, $context = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pconnect(...\func_get_args()); + return $this->initializeLazyObject()->pconnect(...\func_get_args()); } public function persist($key): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->persist(...\func_get_args()); + return $this->initializeLazyObject()->persist(...\func_get_args()); } public function pexpire($key, $timeout, $mode = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpire(...\func_get_args()); + return $this->initializeLazyObject()->pexpire(...\func_get_args()); } public function pexpireAt($key, $timestamp, $mode = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpireAt(...\func_get_args()); + return $this->initializeLazyObject()->pexpireAt(...\func_get_args()); } public function pfadd($key, $elements): \Redis|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfadd(...\func_get_args()); + return $this->initializeLazyObject()->pfadd(...\func_get_args()); } public function pfcount($key_or_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfcount(...\func_get_args()); + return $this->initializeLazyObject()->pfcount(...\func_get_args()); } public function pfmerge($dst, $srckeys): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfmerge(...\func_get_args()); + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } public function ping($message = null): \Redis|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ping(...\func_get_args()); + return $this->initializeLazyObject()->ping(...\func_get_args()); } public function pipeline(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pipeline(...\func_get_args()); + return $this->initializeLazyObject()->pipeline(...\func_get_args()); } public function popen($host, $port = 6379, $timeout = 0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0, $context = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->popen(...\func_get_args()); + return $this->initializeLazyObject()->popen(...\func_get_args()); } public function psetex($key, $expire, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psetex(...\func_get_args()); + return $this->initializeLazyObject()->psetex(...\func_get_args()); } public function psubscribe($patterns, $cb): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psubscribe(...\func_get_args()); + return $this->initializeLazyObject()->psubscribe(...\func_get_args()); } public function pttl($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pttl(...\func_get_args()); + return $this->initializeLazyObject()->pttl(...\func_get_args()); } public function publish($channel, $message): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->publish(...\func_get_args()); + return $this->initializeLazyObject()->publish(...\func_get_args()); } public function pubsub($command, $arg = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pubsub(...\func_get_args()); + return $this->initializeLazyObject()->pubsub(...\func_get_args()); } public function punsubscribe($patterns): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->punsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); } public function rPop($key, $count = 0): \Redis|array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rPop(...\func_get_args()); + return $this->initializeLazyObject()->rPop(...\func_get_args()); } public function randomKey(): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->randomKey(...\func_get_args()); + return $this->initializeLazyObject()->randomKey(...\func_get_args()); } public function rawcommand($command, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rawcommand(...\func_get_args()); + return $this->initializeLazyObject()->rawcommand(...\func_get_args()); } public function rename($old_name, $new_name): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rename(...\func_get_args()); + return $this->initializeLazyObject()->rename(...\func_get_args()); } public function renameNx($key_src, $key_dst): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renameNx(...\func_get_args()); + return $this->initializeLazyObject()->renameNx(...\func_get_args()); } public function restore($key, $ttl, $value, $options = null): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->restore(...\func_get_args()); + return $this->initializeLazyObject()->restore(...\func_get_args()); } public function role(): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->role(...\func_get_args()); + return $this->initializeLazyObject()->role(...\func_get_args()); } public function rpoplpush($srckey, $dstkey): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); } public function sAdd($key, $value, ...$other_values): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sAdd(...\func_get_args()); + return $this->initializeLazyObject()->sAdd(...\func_get_args()); } public function sAddArray($key, $values): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sAddArray(...\func_get_args()); + return $this->initializeLazyObject()->sAddArray(...\func_get_args()); } public function sDiff($key, ...$other_keys): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sDiff(...\func_get_args()); + return $this->initializeLazyObject()->sDiff(...\func_get_args()); } public function sDiffStore($dst, $key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sDiffStore(...\func_get_args()); + return $this->initializeLazyObject()->sDiffStore(...\func_get_args()); } public function sInter($key, ...$other_keys): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sInter(...\func_get_args()); + return $this->initializeLazyObject()->sInter(...\func_get_args()); } public function sintercard($keys, $limit = -1): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sintercard(...\func_get_args()); + return $this->initializeLazyObject()->sintercard(...\func_get_args()); } public function sInterStore($key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sInterStore(...\func_get_args()); + return $this->initializeLazyObject()->sInterStore(...\func_get_args()); } public function sMembers($key): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMembers(...\func_get_args()); + return $this->initializeLazyObject()->sMembers(...\func_get_args()); } public function sMisMember($key, $member, ...$other_members): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMisMember(...\func_get_args()); + return $this->initializeLazyObject()->sMisMember(...\func_get_args()); } public function sMove($src, $dst, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sMove(...\func_get_args()); + return $this->initializeLazyObject()->sMove(...\func_get_args()); } public function sPop($key, $count = 0): \Redis|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sPop(...\func_get_args()); + return $this->initializeLazyObject()->sPop(...\func_get_args()); } public function sRandMember($key, $count = 0): \Redis|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sRandMember(...\func_get_args()); + return $this->initializeLazyObject()->sRandMember(...\func_get_args()); } public function sUnion($key, ...$other_keys): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sUnion(...\func_get_args()); + return $this->initializeLazyObject()->sUnion(...\func_get_args()); } public function sUnionStore($dst, $key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sUnionStore(...\func_get_args()); + return $this->initializeLazyObject()->sUnionStore(...\func_get_args()); } public function save(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->save(...\func_get_args()); + return $this->initializeLazyObject()->save(...\func_get_args()); } public function scan(&$iterator, $pattern = null, $count = 0, $type = null): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scan($iterator, ...\array_slice(\func_get_args(), 1)); + return $this->initializeLazyObject()->scan($iterator, ...\array_slice(\func_get_args(), 1)); } public function scard($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scard(...\func_get_args()); + return $this->initializeLazyObject()->scard(...\func_get_args()); } public function script($command, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->script(...\func_get_args()); + return $this->initializeLazyObject()->script(...\func_get_args()); } public function select($db): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->select(...\func_get_args()); + return $this->initializeLazyObject()->select(...\func_get_args()); } public function set($key, $value, $options = null): \Redis|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->set(...\func_get_args()); + return $this->initializeLazyObject()->set(...\func_get_args()); } public function setBit($key, $idx, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setBit(...\func_get_args()); + return $this->initializeLazyObject()->setBit(...\func_get_args()); } public function setRange($key, $index, $value): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setRange(...\func_get_args()); + return $this->initializeLazyObject()->setRange(...\func_get_args()); } public function setOption($option, $value): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setOption(...\func_get_args()); + return $this->initializeLazyObject()->setOption(...\func_get_args()); } public function setex($key, $expire, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setex(...\func_get_args()); + return $this->initializeLazyObject()->setex(...\func_get_args()); } public function setnx($key, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setnx(...\func_get_args()); + return $this->initializeLazyObject()->setnx(...\func_get_args()); } public function sismember($key, $value): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sismember(...\func_get_args()); + return $this->initializeLazyObject()->sismember(...\func_get_args()); } public function slaveof($host = null, $port = 6379): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slaveof(...\func_get_args()); + return $this->initializeLazyObject()->slaveof(...\func_get_args()); } public function replicaof($host = null, $port = 6379): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->replicaof(...\func_get_args()); + return $this->initializeLazyObject()->replicaof(...\func_get_args()); } public function touch($key_or_array, ...$more_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->touch(...\func_get_args()); + return $this->initializeLazyObject()->touch(...\func_get_args()); } public function slowlog($operation, $length = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slowlog(...\func_get_args()); + return $this->initializeLazyObject()->slowlog(...\func_get_args()); } public function sort($key, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort(...\func_get_args()); + return $this->initializeLazyObject()->sort(...\func_get_args()); } public function sort_ro($key, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort_ro(...\func_get_args()); + return $this->initializeLazyObject()->sort_ro(...\func_get_args()); } public function sortAsc($key, $pattern = null, $get = null, $offset = -1, $count = -1, $store = null): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortAsc(...\func_get_args()); + return $this->initializeLazyObject()->sortAsc(...\func_get_args()); } public function sortAscAlpha($key, $pattern = null, $get = null, $offset = -1, $count = -1, $store = null): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortAscAlpha(...\func_get_args()); + return $this->initializeLazyObject()->sortAscAlpha(...\func_get_args()); } public function sortDesc($key, $pattern = null, $get = null, $offset = -1, $count = -1, $store = null): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortDesc(...\func_get_args()); + return $this->initializeLazyObject()->sortDesc(...\func_get_args()); } public function sortDescAlpha($key, $pattern = null, $get = null, $offset = -1, $count = -1, $store = null): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sortDescAlpha(...\func_get_args()); + return $this->initializeLazyObject()->sortDescAlpha(...\func_get_args()); } public function srem($key, $value, ...$other_values): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srem(...\func_get_args()); + return $this->initializeLazyObject()->srem(...\func_get_args()); } public function sscan($key, &$iterator, $pattern = null, $count = 0): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function ssubscribe($channels, $cb): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ssubscribe(...\func_get_args()); + return $this->initializeLazyObject()->ssubscribe(...\func_get_args()); } public function strlen($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->strlen(...\func_get_args()); + return $this->initializeLazyObject()->strlen(...\func_get_args()); } public function subscribe($channels, $cb): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->subscribe(...\func_get_args()); + return $this->initializeLazyObject()->subscribe(...\func_get_args()); } public function sunsubscribe($channels): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->sunsubscribe(...\func_get_args()); } public function swapdb($src, $dst): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->swapdb(...\func_get_args()); + return $this->initializeLazyObject()->swapdb(...\func_get_args()); } public function time(): \Redis|array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->time(...\func_get_args()); + return $this->initializeLazyObject()->time(...\func_get_args()); } public function ttl($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ttl(...\func_get_args()); + return $this->initializeLazyObject()->ttl(...\func_get_args()); } public function type($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->type(...\func_get_args()); + return $this->initializeLazyObject()->type(...\func_get_args()); } public function unlink($key, ...$other_keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unlink(...\func_get_args()); + return $this->initializeLazyObject()->unlink(...\func_get_args()); } public function unsubscribe($channels): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); } public function unwatch(): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unwatch(...\func_get_args()); + return $this->initializeLazyObject()->unwatch(...\func_get_args()); } public function watch($key, ...$other_keys): \Redis|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->watch(...\func_get_args()); + return $this->initializeLazyObject()->watch(...\func_get_args()); } public function wait($numreplicas, $timeout): false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->wait(...\func_get_args()); + return $this->initializeLazyObject()->wait(...\func_get_args()); } public function xack($key, $group, $ids): false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xack(...\func_get_args()); + return $this->initializeLazyObject()->xack(...\func_get_args()); } public function xadd($key, $id, $values, $maxlen = 0, $approx = false, $nomkstream = false): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xadd(...\func_get_args()); + return $this->initializeLazyObject()->xadd(...\func_get_args()); } public function xautoclaim($key, $group, $consumer, $min_idle, $start, $count = -1, $justid = false): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xautoclaim(...\func_get_args()); + return $this->initializeLazyObject()->xautoclaim(...\func_get_args()); } public function xclaim($key, $group, $consumer, $min_idle, $ids, $options): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xclaim(...\func_get_args()); + return $this->initializeLazyObject()->xclaim(...\func_get_args()); } public function xdel($key, $ids): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xdel(...\func_get_args()); + return $this->initializeLazyObject()->xdel(...\func_get_args()); } public function xgroup($operation, $key = null, $group = null, $id_or_consumer = null, $mkstream = false, $entries_read = -2): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xgroup(...\func_get_args()); + return $this->initializeLazyObject()->xgroup(...\func_get_args()); } public function xinfo($operation, $arg1 = null, $arg2 = null, $count = -1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xinfo(...\func_get_args()); + return $this->initializeLazyObject()->xinfo(...\func_get_args()); } public function xlen($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xlen(...\func_get_args()); + return $this->initializeLazyObject()->xlen(...\func_get_args()); } public function xpending($key, $group, $start = null, $end = null, $count = -1, $consumer = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xpending(...\func_get_args()); + return $this->initializeLazyObject()->xpending(...\func_get_args()); } public function xrange($key, $start, $end, $count = -1): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrange(...\func_get_args()); + return $this->initializeLazyObject()->xrange(...\func_get_args()); } public function xread($streams, $count = -1, $block = -1): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xread(...\func_get_args()); + return $this->initializeLazyObject()->xread(...\func_get_args()); } public function xreadgroup($group, $consumer, $streams, $count = 1, $block = 1): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xreadgroup(...\func_get_args()); + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } public function xrevrange($key, $end, $start, $count = -1): \Redis|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrevrange(...\func_get_args()); + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } public function xtrim($key, $threshold, $approx = false, $minid = false, $limit = -1): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xtrim(...\func_get_args()); + return $this->initializeLazyObject()->xtrim(...\func_get_args()); } public function zAdd($key, $score_or_options, ...$more_scores_and_mems): \Redis|false|float|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zAdd(...\func_get_args()); + return $this->initializeLazyObject()->zAdd(...\func_get_args()); } public function zCard($key): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zCard(...\func_get_args()); + return $this->initializeLazyObject()->zCard(...\func_get_args()); } public function zCount($key, $start, $end): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zCount(...\func_get_args()); + return $this->initializeLazyObject()->zCount(...\func_get_args()); } public function zIncrBy($key, $value, $member): \Redis|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zIncrBy(...\func_get_args()); + return $this->initializeLazyObject()->zIncrBy(...\func_get_args()); } public function zLexCount($key, $min, $max): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zLexCount(...\func_get_args()); + return $this->initializeLazyObject()->zLexCount(...\func_get_args()); } public function zMscore($key, $member, ...$other_members): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zMscore(...\func_get_args()); + return $this->initializeLazyObject()->zMscore(...\func_get_args()); } public function zPopMax($key, $count = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zPopMax(...\func_get_args()); + return $this->initializeLazyObject()->zPopMax(...\func_get_args()); } public function zPopMin($key, $count = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zPopMin(...\func_get_args()); + return $this->initializeLazyObject()->zPopMin(...\func_get_args()); } public function zRange($key, $start, $end, $options = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRange(...\func_get_args()); + return $this->initializeLazyObject()->zRange(...\func_get_args()); } public function zRangeByLex($key, $min, $max, $offset = -1, $count = -1): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRangeByLex(...\func_get_args()); } public function zRangeByScore($key, $start, $end, $options = []): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRangeByScore(...\func_get_args()); } public function zrangestore($dstkey, $srckey, $start, $end, $options = null): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangestore(...\func_get_args()); + return $this->initializeLazyObject()->zrangestore(...\func_get_args()); } public function zRandMember($key, $options = null): \Redis|array|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRandMember(...\func_get_args()); + return $this->initializeLazyObject()->zRandMember(...\func_get_args()); } public function zRank($key, $member): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRank(...\func_get_args()); + return $this->initializeLazyObject()->zRank(...\func_get_args()); } public function zRem($key, $member, ...$other_members): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRem(...\func_get_args()); + return $this->initializeLazyObject()->zRem(...\func_get_args()); } public function zRemRangeByLex($key, $min, $max): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByLex(...\func_get_args()); } public function zRemRangeByRank($key, $start, $end): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByRank(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByRank(...\func_get_args()); } public function zRemRangeByScore($key, $start, $end): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRemRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRemRangeByScore(...\func_get_args()); } public function zRevRange($key, $start, $end, $scores = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRange(...\func_get_args()); + return $this->initializeLazyObject()->zRevRange(...\func_get_args()); } public function zRevRangeByLex($key, $max, $min, $offset = -1, $count = -1): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRangeByLex(...\func_get_args()); + return $this->initializeLazyObject()->zRevRangeByLex(...\func_get_args()); } public function zRevRangeByScore($key, $max, $min, $options = []): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRangeByScore(...\func_get_args()); + return $this->initializeLazyObject()->zRevRangeByScore(...\func_get_args()); } public function zRevRank($key, $member): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zRevRank(...\func_get_args()); + return $this->initializeLazyObject()->zRevRank(...\func_get_args()); } public function zScore($key, $member): \Redis|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zScore(...\func_get_args()); + return $this->initializeLazyObject()->zScore(...\func_get_args()); } public function zdiff($keys, $options = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiff(...\func_get_args()); + return $this->initializeLazyObject()->zdiff(...\func_get_args()); } public function zdiffstore($dst, $keys): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->zdiffstore(...\func_get_args()); } public function zinter($keys, $weights = null, $options = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinter(...\func_get_args()); + return $this->initializeLazyObject()->zinter(...\func_get_args()); } public function zintercard($keys, $limit = -1): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zintercard(...\func_get_args()); + return $this->initializeLazyObject()->zintercard(...\func_get_args()); } public function zinterstore($dst, $keys, $weights = null, $aggregate = null): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinterstore(...\func_get_args()); + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } public function zscan($key, &$iterator, $pattern = null, $count = 0): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function zunion($keys, $weights = null, $options = null): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunion(...\func_get_args()); + return $this->initializeLazyObject()->zunion(...\func_get_args()); } public function zunionstore($dst, $keys, $weights = null, $aggregate = null): \Redis|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunionstore(...\func_get_args()); + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } } diff --git a/Traits/RedisCluster5Proxy.php b/Traits/RedisCluster5Proxy.php index 511c53dd..43f34047 100644 --- a/Traits/RedisCluster5Proxy.php +++ b/Traits/RedisCluster5Proxy.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\VarExporter\LazyObjectInterface; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Contracts\Service\ResetInterface; // Help opcache.preload discover always-needed symbols @@ -25,959 +24,957 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class RedisCluster5Proxy extends \RedisCluster implements ResetInterface, LazyObjectInterface { - use LazyProxyTrait { + use RedisProxyTrait { resetLazyObject as reset; } - private const LAZY_OBJECT_PROPERTY_SCOPES = []; - public function __construct($name, $seeds = null, $timeout = null, $read_timeout = null, $persistent = null, #[\SensitiveParameter] $auth = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->__construct(...\func_get_args()); + $this->initializeLazyObject()->__construct(...\func_get_args()); } public function _masters() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_masters(...\func_get_args()); + return $this->initializeLazyObject()->_masters(...\func_get_args()); } public function _prefix($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_prefix(...\func_get_args()); + return $this->initializeLazyObject()->_prefix(...\func_get_args()); } public function _redir() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_redir(...\func_get_args()); + return $this->initializeLazyObject()->_redir(...\func_get_args()); } public function _serialize($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_serialize(...\func_get_args()); + return $this->initializeLazyObject()->_serialize(...\func_get_args()); } public function _unserialize($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unserialize(...\func_get_args()); + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); } public function _compress($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_compress(...\func_get_args()); + return $this->initializeLazyObject()->_compress(...\func_get_args()); } public function _uncompress($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_uncompress(...\func_get_args()); + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); } public function _pack($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_pack(...\func_get_args()); + return $this->initializeLazyObject()->_pack(...\func_get_args()); } public function _unpack($value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unpack(...\func_get_args()); + return $this->initializeLazyObject()->_unpack(...\func_get_args()); } public function acl($key_or_address, $subcmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->acl(...\func_get_args()); + return $this->initializeLazyObject()->acl(...\func_get_args()); } public function append($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->append(...\func_get_args()); + return $this->initializeLazyObject()->append(...\func_get_args()); } public function bgrewriteaof($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgrewriteaof(...\func_get_args()); + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } public function bgsave($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgsave(...\func_get_args()); + return $this->initializeLazyObject()->bgsave(...\func_get_args()); } public function bitcount($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitcount(...\func_get_args()); + return $this->initializeLazyObject()->bitcount(...\func_get_args()); } public function bitop($operation, $ret_key, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitop(...\func_get_args()); + return $this->initializeLazyObject()->bitop(...\func_get_args()); } public function bitpos($key, $bit, $start = null, $end = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitpos(...\func_get_args()); + return $this->initializeLazyObject()->bitpos(...\func_get_args()); } public function blpop($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blpop(...\func_get_args()); + return $this->initializeLazyObject()->blpop(...\func_get_args()); } public function brpop($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpop(...\func_get_args()); + return $this->initializeLazyObject()->brpop(...\func_get_args()); } public function brpoplpush($src, $dst, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } public function clearlasterror() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearlasterror(...\func_get_args()); + return $this->initializeLazyObject()->clearlasterror(...\func_get_args()); } public function bzpopmax($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmax(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmax(...\func_get_args()); } public function bzpopmin($key, $timeout_or_key, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmin(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmin(...\func_get_args()); } public function client($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->client(...\func_get_args()); + return $this->initializeLazyObject()->client(...\func_get_args()); } public function close() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->close(...\func_get_args()); + return $this->initializeLazyObject()->close(...\func_get_args()); } public function cluster($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->cluster(...\func_get_args()); + return $this->initializeLazyObject()->cluster(...\func_get_args()); } public function command(...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->command(...\func_get_args()); + return $this->initializeLazyObject()->command(...\func_get_args()); } public function config($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->config(...\func_get_args()); + return $this->initializeLazyObject()->config(...\func_get_args()); } public function dbsize($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dbsize(...\func_get_args()); + return $this->initializeLazyObject()->dbsize(...\func_get_args()); } public function decr($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decr(...\func_get_args()); + return $this->initializeLazyObject()->decr(...\func_get_args()); } public function decrby($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrby(...\func_get_args()); + return $this->initializeLazyObject()->decrby(...\func_get_args()); } public function del($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->del(...\func_get_args()); + return $this->initializeLazyObject()->del(...\func_get_args()); } public function discard() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->discard(...\func_get_args()); + return $this->initializeLazyObject()->discard(...\func_get_args()); } public function dump($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dump(...\func_get_args()); + return $this->initializeLazyObject()->dump(...\func_get_args()); } public function echo($msg) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args()); + return $this->initializeLazyObject()->echo(...\func_get_args()); } public function eval($script, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval(...\func_get_args()); + return $this->initializeLazyObject()->eval(...\func_get_args()); } public function evalsha($script_sha, $args = null, $num_keys = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha(...\func_get_args()); + return $this->initializeLazyObject()->evalsha(...\func_get_args()); } public function exec() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exec(...\func_get_args()); + return $this->initializeLazyObject()->exec(...\func_get_args()); } public function exists($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exists(...\func_get_args()); + return $this->initializeLazyObject()->exists(...\func_get_args()); } public function expire($key, $timeout) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expire(...\func_get_args()); + return $this->initializeLazyObject()->expire(...\func_get_args()); } public function expireat($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expireat(...\func_get_args()); + return $this->initializeLazyObject()->expireat(...\func_get_args()); } public function flushall($key_or_address, $async = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushall(...\func_get_args()); + return $this->initializeLazyObject()->flushall(...\func_get_args()); } public function flushdb($key_or_address, $async = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushdb(...\func_get_args()); + return $this->initializeLazyObject()->flushdb(...\func_get_args()); } public function geoadd($key, $lng, $lat, $member, ...$other_triples) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geoadd(...\func_get_args()); + return $this->initializeLazyObject()->geoadd(...\func_get_args()); } public function geodist($key, $src, $dst, $unit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geodist(...\func_get_args()); + return $this->initializeLazyObject()->geodist(...\func_get_args()); } public function geohash($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geohash(...\func_get_args()); + return $this->initializeLazyObject()->geohash(...\func_get_args()); } public function geopos($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geopos(...\func_get_args()); + return $this->initializeLazyObject()->geopos(...\func_get_args()); } public function georadius($key, $lng, $lan, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius(...\func_get_args()); + return $this->initializeLazyObject()->georadius(...\func_get_args()); } public function georadius_ro($key, $lng, $lan, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } public function georadiusbymember($key, $member, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); } public function georadiusbymember_ro($key, $member, $radius, $unit, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); } public function get($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->get(...\func_get_args()); + return $this->initializeLazyObject()->get(...\func_get_args()); } public function getbit($key, $offset) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getbit(...\func_get_args()); + return $this->initializeLazyObject()->getbit(...\func_get_args()); } public function getlasterror() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getlasterror(...\func_get_args()); + return $this->initializeLazyObject()->getlasterror(...\func_get_args()); } public function getmode() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getmode(...\func_get_args()); + return $this->initializeLazyObject()->getmode(...\func_get_args()); } public function getoption($option) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getoption(...\func_get_args()); + return $this->initializeLazyObject()->getoption(...\func_get_args()); } public function getrange($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getrange(...\func_get_args()); + return $this->initializeLazyObject()->getrange(...\func_get_args()); } public function getset($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getset(...\func_get_args()); + return $this->initializeLazyObject()->getset(...\func_get_args()); } public function hdel($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hdel(...\func_get_args()); + return $this->initializeLazyObject()->hdel(...\func_get_args()); } public function hexists($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexists(...\func_get_args()); + return $this->initializeLazyObject()->hexists(...\func_get_args()); } public function hget($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hget(...\func_get_args()); + return $this->initializeLazyObject()->hget(...\func_get_args()); } public function hgetall($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetall(...\func_get_args()); + return $this->initializeLazyObject()->hgetall(...\func_get_args()); } public function hincrby($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrby(...\func_get_args()); + return $this->initializeLazyObject()->hincrby(...\func_get_args()); } public function hincrbyfloat($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->hincrbyfloat(...\func_get_args()); } public function hkeys($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hkeys(...\func_get_args()); + return $this->initializeLazyObject()->hkeys(...\func_get_args()); } public function hlen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hlen(...\func_get_args()); + return $this->initializeLazyObject()->hlen(...\func_get_args()); } public function hmget($key, $keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmget(...\func_get_args()); + return $this->initializeLazyObject()->hmget(...\func_get_args()); } public function hmset($key, $pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmset(...\func_get_args()); + return $this->initializeLazyObject()->hmset(...\func_get_args()); } public function hscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->hscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function hset($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hset(...\func_get_args()); + return $this->initializeLazyObject()->hset(...\func_get_args()); } public function hsetnx($key, $member, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hsetnx(...\func_get_args()); + return $this->initializeLazyObject()->hsetnx(...\func_get_args()); } public function hstrlen($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hstrlen(...\func_get_args()); + return $this->initializeLazyObject()->hstrlen(...\func_get_args()); } public function hvals($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hvals(...\func_get_args()); + return $this->initializeLazyObject()->hvals(...\func_get_args()); } public function incr($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incr(...\func_get_args()); + return $this->initializeLazyObject()->incr(...\func_get_args()); } public function incrby($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrby(...\func_get_args()); + return $this->initializeLazyObject()->incrby(...\func_get_args()); } public function incrbyfloat($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->incrbyfloat(...\func_get_args()); } public function info($key_or_address, $option = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->info(...\func_get_args()); + return $this->initializeLazyObject()->info(...\func_get_args()); } public function keys($pattern) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->keys(...\func_get_args()); + return $this->initializeLazyObject()->keys(...\func_get_args()); } public function lastsave($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lastsave(...\func_get_args()); + return $this->initializeLazyObject()->lastsave(...\func_get_args()); } public function lget($key, $index) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lget(...\func_get_args()); + return $this->initializeLazyObject()->lget(...\func_get_args()); } public function lindex($key, $index) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lindex(...\func_get_args()); + return $this->initializeLazyObject()->lindex(...\func_get_args()); } public function linsert($key, $position, $pivot, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->linsert(...\func_get_args()); + return $this->initializeLazyObject()->linsert(...\func_get_args()); } public function llen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->llen(...\func_get_args()); + return $this->initializeLazyObject()->llen(...\func_get_args()); } public function lpop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpop(...\func_get_args()); + return $this->initializeLazyObject()->lpop(...\func_get_args()); } public function lpush($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpush(...\func_get_args()); + return $this->initializeLazyObject()->lpush(...\func_get_args()); } public function lpushx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpushx(...\func_get_args()); + return $this->initializeLazyObject()->lpushx(...\func_get_args()); } public function lrange($key, $start, $end) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrange(...\func_get_args()); + return $this->initializeLazyObject()->lrange(...\func_get_args()); } public function lrem($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrem(...\func_get_args()); + return $this->initializeLazyObject()->lrem(...\func_get_args()); } public function lset($key, $index, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lset(...\func_get_args()); + return $this->initializeLazyObject()->lset(...\func_get_args()); } public function ltrim($key, $start, $stop) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ltrim(...\func_get_args()); + return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public function mget($keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mget(...\func_get_args()); + return $this->initializeLazyObject()->mget(...\func_get_args()); } public function mset($pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mset(...\func_get_args()); + return $this->initializeLazyObject()->mset(...\func_get_args()); } public function msetnx($pairs) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->msetnx(...\func_get_args()); + return $this->initializeLazyObject()->msetnx(...\func_get_args()); } public function multi() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->multi(...\func_get_args()); + return $this->initializeLazyObject()->multi(...\func_get_args()); } public function object($field, $key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->object(...\func_get_args()); + return $this->initializeLazyObject()->object(...\func_get_args()); } public function persist($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->persist(...\func_get_args()); + return $this->initializeLazyObject()->persist(...\func_get_args()); } public function pexpire($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpire(...\func_get_args()); + return $this->initializeLazyObject()->pexpire(...\func_get_args()); } public function pexpireat($key, $timestamp) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpireat(...\func_get_args()); + return $this->initializeLazyObject()->pexpireat(...\func_get_args()); } public function pfadd($key, $elements) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfadd(...\func_get_args()); + return $this->initializeLazyObject()->pfadd(...\func_get_args()); } public function pfcount($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfcount(...\func_get_args()); + return $this->initializeLazyObject()->pfcount(...\func_get_args()); } public function pfmerge($dstkey, $keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfmerge(...\func_get_args()); + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } public function ping($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ping(...\func_get_args()); + return $this->initializeLazyObject()->ping(...\func_get_args()); } public function psetex($key, $expire, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psetex(...\func_get_args()); + return $this->initializeLazyObject()->psetex(...\func_get_args()); } public function psubscribe($patterns, $callback) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psubscribe(...\func_get_args()); + return $this->initializeLazyObject()->psubscribe(...\func_get_args()); } public function pttl($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pttl(...\func_get_args()); + return $this->initializeLazyObject()->pttl(...\func_get_args()); } public function publish($channel, $message) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->publish(...\func_get_args()); + return $this->initializeLazyObject()->publish(...\func_get_args()); } public function pubsub($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pubsub(...\func_get_args()); + return $this->initializeLazyObject()->pubsub(...\func_get_args()); } public function punsubscribe($pattern, ...$other_patterns) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->punsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); } public function randomkey($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->randomkey(...\func_get_args()); + return $this->initializeLazyObject()->randomkey(...\func_get_args()); } public function rawcommand($cmd, ...$args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rawcommand(...\func_get_args()); + return $this->initializeLazyObject()->rawcommand(...\func_get_args()); } public function rename($key, $newkey) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rename(...\func_get_args()); + return $this->initializeLazyObject()->rename(...\func_get_args()); } public function renamenx($key, $newkey) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renamenx(...\func_get_args()); + return $this->initializeLazyObject()->renamenx(...\func_get_args()); } public function restore($ttl, $key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->restore(...\func_get_args()); + return $this->initializeLazyObject()->restore(...\func_get_args()); } public function role() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->role(...\func_get_args()); + return $this->initializeLazyObject()->role(...\func_get_args()); } public function rpop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpop(...\func_get_args()); + return $this->initializeLazyObject()->rpop(...\func_get_args()); } public function rpoplpush($src, $dst) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); } public function rpush($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpush(...\func_get_args()); + return $this->initializeLazyObject()->rpush(...\func_get_args()); } public function rpushx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpushx(...\func_get_args()); + return $this->initializeLazyObject()->rpushx(...\func_get_args()); } public function sadd($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sadd(...\func_get_args()); + return $this->initializeLazyObject()->sadd(...\func_get_args()); } public function saddarray($key, $options) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->saddarray(...\func_get_args()); + return $this->initializeLazyObject()->saddarray(...\func_get_args()); } public function save($key_or_address) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->save(...\func_get_args()); + return $this->initializeLazyObject()->save(...\func_get_args()); } public function scan(&$i_iterator, $str_node, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scan($i_iterator, ...\array_slice(\func_get_args(), 1)); + return $this->initializeLazyObject()->scan($i_iterator, ...\array_slice(\func_get_args(), 1)); } public function scard($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scard(...\func_get_args()); + return $this->initializeLazyObject()->scard(...\func_get_args()); } public function script($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->script(...\func_get_args()); + return $this->initializeLazyObject()->script(...\func_get_args()); } public function sdiff($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiff(...\func_get_args()); + return $this->initializeLazyObject()->sdiff(...\func_get_args()); } public function sdiffstore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->sdiffstore(...\func_get_args()); } public function set($key, $value, $opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->set(...\func_get_args()); + return $this->initializeLazyObject()->set(...\func_get_args()); } public function setbit($key, $offset, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setbit(...\func_get_args()); + return $this->initializeLazyObject()->setbit(...\func_get_args()); } public function setex($key, $expire, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setex(...\func_get_args()); + return $this->initializeLazyObject()->setex(...\func_get_args()); } public function setnx($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setnx(...\func_get_args()); + return $this->initializeLazyObject()->setnx(...\func_get_args()); } public function setoption($option, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setoption(...\func_get_args()); + return $this->initializeLazyObject()->setoption(...\func_get_args()); } public function setrange($key, $offset, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setrange(...\func_get_args()); + return $this->initializeLazyObject()->setrange(...\func_get_args()); } public function sinter($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinter(...\func_get_args()); + return $this->initializeLazyObject()->sinter(...\func_get_args()); } public function sinterstore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinterstore(...\func_get_args()); + return $this->initializeLazyObject()->sinterstore(...\func_get_args()); } public function sismember($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sismember(...\func_get_args()); + return $this->initializeLazyObject()->sismember(...\func_get_args()); } public function slowlog($key_or_address, $arg = null, ...$other_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slowlog(...\func_get_args()); + return $this->initializeLazyObject()->slowlog(...\func_get_args()); } public function smembers($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smembers(...\func_get_args()); + return $this->initializeLazyObject()->smembers(...\func_get_args()); } public function smove($src, $dst, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smove(...\func_get_args()); + return $this->initializeLazyObject()->smove(...\func_get_args()); } public function sort($key, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort(...\func_get_args()); + return $this->initializeLazyObject()->sort(...\func_get_args()); } public function spop($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->spop(...\func_get_args()); + return $this->initializeLazyObject()->spop(...\func_get_args()); } public function srandmember($key, $count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srandmember(...\func_get_args()); + return $this->initializeLazyObject()->srandmember(...\func_get_args()); } public function srem($key, $value) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srem(...\func_get_args()); + return $this->initializeLazyObject()->srem(...\func_get_args()); } public function sscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->sscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function strlen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->strlen(...\func_get_args()); + return $this->initializeLazyObject()->strlen(...\func_get_args()); } public function subscribe($channels, $callback) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->subscribe(...\func_get_args()); + return $this->initializeLazyObject()->subscribe(...\func_get_args()); } public function sunion($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunion(...\func_get_args()); + return $this->initializeLazyObject()->sunion(...\func_get_args()); } public function sunionstore($dst, $key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunionstore(...\func_get_args()); + return $this->initializeLazyObject()->sunionstore(...\func_get_args()); } public function time() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->time(...\func_get_args()); + return $this->initializeLazyObject()->time(...\func_get_args()); } public function ttl($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ttl(...\func_get_args()); + return $this->initializeLazyObject()->ttl(...\func_get_args()); } public function type($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->type(...\func_get_args()); + return $this->initializeLazyObject()->type(...\func_get_args()); } public function unsubscribe($channel, ...$other_channels) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); } public function unlink($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unlink(...\func_get_args()); + return $this->initializeLazyObject()->unlink(...\func_get_args()); } public function unwatch() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unwatch(...\func_get_args()); + return $this->initializeLazyObject()->unwatch(...\func_get_args()); } public function watch($key, ...$other_keys) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->watch(...\func_get_args()); + return $this->initializeLazyObject()->watch(...\func_get_args()); } public function xack($str_key, $str_group, $arr_ids) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xack(...\func_get_args()); + return $this->initializeLazyObject()->xack(...\func_get_args()); } public function xadd($str_key, $str_id, $arr_fields, $i_maxlen = null, $boo_approximate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xadd(...\func_get_args()); + return $this->initializeLazyObject()->xadd(...\func_get_args()); } public function xclaim($str_key, $str_group, $str_consumer, $i_min_idle, $arr_ids, $arr_opts = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xclaim(...\func_get_args()); + return $this->initializeLazyObject()->xclaim(...\func_get_args()); } public function xdel($str_key, $arr_ids) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xdel(...\func_get_args()); + return $this->initializeLazyObject()->xdel(...\func_get_args()); } public function xgroup($str_operation, $str_key = null, $str_arg1 = null, $str_arg2 = null, $str_arg3 = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xgroup(...\func_get_args()); + return $this->initializeLazyObject()->xgroup(...\func_get_args()); } public function xinfo($str_cmd, $str_key = null, $str_group = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xinfo(...\func_get_args()); + return $this->initializeLazyObject()->xinfo(...\func_get_args()); } public function xlen($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xlen(...\func_get_args()); + return $this->initializeLazyObject()->xlen(...\func_get_args()); } public function xpending($str_key, $str_group, $str_start = null, $str_end = null, $i_count = null, $str_consumer = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xpending(...\func_get_args()); + return $this->initializeLazyObject()->xpending(...\func_get_args()); } public function xrange($str_key, $str_start, $str_end, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrange(...\func_get_args()); + return $this->initializeLazyObject()->xrange(...\func_get_args()); } public function xread($arr_streams, $i_count = null, $i_block = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xread(...\func_get_args()); + return $this->initializeLazyObject()->xread(...\func_get_args()); } public function xreadgroup($str_group, $str_consumer, $arr_streams, $i_count = null, $i_block = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xreadgroup(...\func_get_args()); + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } public function xrevrange($str_key, $str_start, $str_end, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrevrange(...\func_get_args()); + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } public function xtrim($str_key, $i_maxlen, $boo_approximate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xtrim(...\func_get_args()); + return $this->initializeLazyObject()->xtrim(...\func_get_args()); } public function zadd($key, $score, $value, ...$extra_args) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zadd(...\func_get_args()); + return $this->initializeLazyObject()->zadd(...\func_get_args()); } public function zcard($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcard(...\func_get_args()); + return $this->initializeLazyObject()->zcard(...\func_get_args()); } public function zcount($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcount(...\func_get_args()); + return $this->initializeLazyObject()->zcount(...\func_get_args()); } public function zincrby($key, $value, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zincrby(...\func_get_args()); + return $this->initializeLazyObject()->zincrby(...\func_get_args()); } public function zinterstore($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinterstore(...\func_get_args()); + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } public function zlexcount($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zlexcount(...\func_get_args()); + return $this->initializeLazyObject()->zlexcount(...\func_get_args()); } public function zpopmax($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmax(...\func_get_args()); + return $this->initializeLazyObject()->zpopmax(...\func_get_args()); } public function zpopmin($key) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmin(...\func_get_args()); + return $this->initializeLazyObject()->zpopmin(...\func_get_args()); } public function zrange($key, $start, $end, $scores = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrange(...\func_get_args()); + return $this->initializeLazyObject()->zrange(...\func_get_args()); } public function zrangebylex($key, $min, $max, $offset = null, $limit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrangebylex(...\func_get_args()); } public function zrangebyscore($key, $start, $end, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrangebyscore(...\func_get_args()); } public function zrank($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrank(...\func_get_args()); + return $this->initializeLazyObject()->zrank(...\func_get_args()); } public function zrem($key, $member, ...$other_members) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrem(...\func_get_args()); + return $this->initializeLazyObject()->zrem(...\func_get_args()); } public function zremrangebylex($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebylex(...\func_get_args()); } public function zremrangebyrank($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyrank(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyrank(...\func_get_args()); } public function zremrangebyscore($key, $min, $max) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyscore(...\func_get_args()); } public function zrevrange($key, $start, $end, $scores = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrange(...\func_get_args()); + return $this->initializeLazyObject()->zrevrange(...\func_get_args()); } public function zrevrangebylex($key, $min, $max, $offset = null, $limit = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebylex(...\func_get_args()); } public function zrevrangebyscore($key, $start, $end, $options = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebyscore(...\func_get_args()); } public function zrevrank($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrank(...\func_get_args()); + return $this->initializeLazyObject()->zrevrank(...\func_get_args()); } public function zscan($str_key, &$i_iterator, $str_pattern = null, $i_count = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->zscan($str_key, $i_iterator, ...\array_slice(\func_get_args(), 2)); } public function zscore($key, $member) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscore(...\func_get_args()); + return $this->initializeLazyObject()->zscore(...\func_get_args()); } public function zunionstore($key, $keys, $weights = null, $aggregate = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunionstore(...\func_get_args()); + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } } diff --git a/Traits/RedisCluster6Proxy.php b/Traits/RedisCluster6Proxy.php index fafc4acf..8afdb65e 100644 --- a/Traits/RedisCluster6Proxy.php +++ b/Traits/RedisCluster6Proxy.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\VarExporter\LazyObjectInterface; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Contracts\Service\ResetInterface; // Help opcache.preload discover always-needed symbols @@ -25,1119 +24,1117 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class RedisCluster6Proxy extends \RedisCluster implements ResetInterface, LazyObjectInterface { - use LazyProxyTrait { + use RedisProxyTrait { resetLazyObject as reset; } - private const LAZY_OBJECT_PROPERTY_SCOPES = []; - public function __construct($name, $seeds = null, $timeout = 0, $read_timeout = 0, $persistent = false, #[\SensitiveParameter] $auth = null, $context = null) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->__construct(...\func_get_args()); + $this->initializeLazyObject()->__construct(...\func_get_args()); } public function _compress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_compress(...\func_get_args()); + return $this->initializeLazyObject()->_compress(...\func_get_args()); } public function _uncompress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_uncompress(...\func_get_args()); + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); } public function _serialize($value): bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_serialize(...\func_get_args()); + return $this->initializeLazyObject()->_serialize(...\func_get_args()); } public function _unserialize($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unserialize(...\func_get_args()); + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); } public function _pack($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_pack(...\func_get_args()); + return $this->initializeLazyObject()->_pack(...\func_get_args()); } public function _unpack($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unpack(...\func_get_args()); + return $this->initializeLazyObject()->_unpack(...\func_get_args()); } public function _prefix($key): bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_prefix(...\func_get_args()); + return $this->initializeLazyObject()->_prefix(...\func_get_args()); } public function _masters(): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_masters(...\func_get_args()); + return $this->initializeLazyObject()->_masters(...\func_get_args()); } public function _redir(): ?string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_redir(...\func_get_args()); + return $this->initializeLazyObject()->_redir(...\func_get_args()); } public function acl($key_or_address, $subcmd, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->acl(...\func_get_args()); + return $this->initializeLazyObject()->acl(...\func_get_args()); } public function append($key, $value): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->append(...\func_get_args()); + return $this->initializeLazyObject()->append(...\func_get_args()); } public function bgrewriteaof($key_or_address): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgrewriteaof(...\func_get_args()); + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } public function bgsave($key_or_address): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgsave(...\func_get_args()); + return $this->initializeLazyObject()->bgsave(...\func_get_args()); } public function bitcount($key, $start = 0, $end = -1, $bybit = false): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitcount(...\func_get_args()); + return $this->initializeLazyObject()->bitcount(...\func_get_args()); } public function bitop($operation, $deskey, $srckey, ...$otherkeys): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitop(...\func_get_args()); + return $this->initializeLazyObject()->bitop(...\func_get_args()); } public function bitpos($key, $bit, $start = 0, $end = -1, $bybit = false): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitpos(...\func_get_args()); + return $this->initializeLazyObject()->bitpos(...\func_get_args()); } public function blpop($key, $timeout_or_key, ...$extra_args): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blpop(...\func_get_args()); + return $this->initializeLazyObject()->blpop(...\func_get_args()); } public function brpop($key, $timeout_or_key, ...$extra_args): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpop(...\func_get_args()); + return $this->initializeLazyObject()->brpop(...\func_get_args()); } public function brpoplpush($srckey, $deskey, $timeout): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } public function lmove($src, $dst, $wherefrom, $whereto): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lmove(...\func_get_args()); + return $this->initializeLazyObject()->lmove(...\func_get_args()); } public function blmove($src, $dst, $wherefrom, $whereto, $timeout): \Redis|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmove(...\func_get_args()); + return $this->initializeLazyObject()->blmove(...\func_get_args()); } public function bzpopmax($key, $timeout_or_key, ...$extra_args): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmax(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmax(...\func_get_args()); } public function bzpopmin($key, $timeout_or_key, ...$extra_args): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmin(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmin(...\func_get_args()); } public function bzmpop($timeout, $keys, $from, $count = 1): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzmpop(...\func_get_args()); + return $this->initializeLazyObject()->bzmpop(...\func_get_args()); } public function zmpop($keys, $from, $count = 1): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zmpop(...\func_get_args()); + return $this->initializeLazyObject()->zmpop(...\func_get_args()); } public function blmpop($timeout, $keys, $from, $count = 1): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmpop(...\func_get_args()); + return $this->initializeLazyObject()->blmpop(...\func_get_args()); } public function lmpop($keys, $from, $count = 1): \RedisCluster|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lmpop(...\func_get_args()); + return $this->initializeLazyObject()->lmpop(...\func_get_args()); } public function clearlasterror(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearlasterror(...\func_get_args()); + return $this->initializeLazyObject()->clearlasterror(...\func_get_args()); } public function client($key_or_address, $subcommand, $arg = null): array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->client(...\func_get_args()); + return $this->initializeLazyObject()->client(...\func_get_args()); } public function close(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->close(...\func_get_args()); + return $this->initializeLazyObject()->close(...\func_get_args()); } public function cluster($key_or_address, $command, ...$extra_args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->cluster(...\func_get_args()); + return $this->initializeLazyObject()->cluster(...\func_get_args()); } public function command(...$extra_args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->command(...\func_get_args()); + return $this->initializeLazyObject()->command(...\func_get_args()); } public function config($key_or_address, $subcommand, ...$extra_args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->config(...\func_get_args()); + return $this->initializeLazyObject()->config(...\func_get_args()); } public function dbsize($key_or_address): \RedisCluster|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dbsize(...\func_get_args()); + return $this->initializeLazyObject()->dbsize(...\func_get_args()); } public function copy($src, $dst, $options = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args()); + return $this->initializeLazyObject()->copy(...\func_get_args()); } public function decr($key, $by = 1): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decr(...\func_get_args()); + return $this->initializeLazyObject()->decr(...\func_get_args()); } public function decrby($key, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrby(...\func_get_args()); + return $this->initializeLazyObject()->decrby(...\func_get_args()); } public function decrbyfloat($key, $value): float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->decrbyfloat(...\func_get_args()); } public function del($key, ...$other_keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->del(...\func_get_args()); + return $this->initializeLazyObject()->del(...\func_get_args()); } public function discard(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->discard(...\func_get_args()); + return $this->initializeLazyObject()->discard(...\func_get_args()); } public function dump($key): \RedisCluster|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dump(...\func_get_args()); + return $this->initializeLazyObject()->dump(...\func_get_args()); } public function echo($key_or_address, $msg): \RedisCluster|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args()); + return $this->initializeLazyObject()->echo(...\func_get_args()); } public function eval($script, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval(...\func_get_args()); + return $this->initializeLazyObject()->eval(...\func_get_args()); } public function eval_ro($script, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval_ro(...\func_get_args()); + return $this->initializeLazyObject()->eval_ro(...\func_get_args()); } public function evalsha($script_sha, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha(...\func_get_args()); + return $this->initializeLazyObject()->evalsha(...\func_get_args()); } public function evalsha_ro($script_sha, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha_ro(...\func_get_args()); + return $this->initializeLazyObject()->evalsha_ro(...\func_get_args()); } public function exec(): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exec(...\func_get_args()); + return $this->initializeLazyObject()->exec(...\func_get_args()); } public function exists($key, ...$other_keys): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exists(...\func_get_args()); + return $this->initializeLazyObject()->exists(...\func_get_args()); } public function touch($key, ...$other_keys): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->touch(...\func_get_args()); + return $this->initializeLazyObject()->touch(...\func_get_args()); } public function expire($key, $timeout, $mode = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expire(...\func_get_args()); + return $this->initializeLazyObject()->expire(...\func_get_args()); } public function expireat($key, $timestamp, $mode = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expireat(...\func_get_args()); + return $this->initializeLazyObject()->expireat(...\func_get_args()); } public function expiretime($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expiretime(...\func_get_args()); + return $this->initializeLazyObject()->expiretime(...\func_get_args()); } public function pexpiretime($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpiretime(...\func_get_args()); + return $this->initializeLazyObject()->pexpiretime(...\func_get_args()); } public function flushall($key_or_address, $async = false): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushall(...\func_get_args()); + return $this->initializeLazyObject()->flushall(...\func_get_args()); } public function flushdb($key_or_address, $async = false): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushdb(...\func_get_args()); + return $this->initializeLazyObject()->flushdb(...\func_get_args()); } public function geoadd($key, $lng, $lat, $member, ...$other_triples_and_options): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geoadd(...\func_get_args()); + return $this->initializeLazyObject()->geoadd(...\func_get_args()); } public function geodist($key, $src, $dest, $unit = null): \RedisCluster|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geodist(...\func_get_args()); + return $this->initializeLazyObject()->geodist(...\func_get_args()); } public function geohash($key, $member, ...$other_members): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geohash(...\func_get_args()); + return $this->initializeLazyObject()->geohash(...\func_get_args()); } public function geopos($key, $member, ...$other_members): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geopos(...\func_get_args()); + return $this->initializeLazyObject()->geopos(...\func_get_args()); } public function georadius($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius(...\func_get_args()); + return $this->initializeLazyObject()->georadius(...\func_get_args()); } public function georadius_ro($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } public function georadiusbymember($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); } public function georadiusbymember_ro($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); } public function geosearch($key, $position, $shape, $unit, $options = []): \RedisCluster|array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearch(...\func_get_args()); + return $this->initializeLazyObject()->geosearch(...\func_get_args()); } public function geosearchstore($dst, $src, $position, $shape, $unit, $options = []): \RedisCluster|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearchstore(...\func_get_args()); + return $this->initializeLazyObject()->geosearchstore(...\func_get_args()); } public function get($key): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->get(...\func_get_args()); + return $this->initializeLazyObject()->get(...\func_get_args()); } public function getbit($key, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getbit(...\func_get_args()); + return $this->initializeLazyObject()->getbit(...\func_get_args()); } public function getlasterror(): ?string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getlasterror(...\func_get_args()); + return $this->initializeLazyObject()->getlasterror(...\func_get_args()); } public function getmode(): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getmode(...\func_get_args()); + return $this->initializeLazyObject()->getmode(...\func_get_args()); } public function getoption($option): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getoption(...\func_get_args()); + return $this->initializeLazyObject()->getoption(...\func_get_args()); } public function getrange($key, $start, $end): \RedisCluster|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getrange(...\func_get_args()); + return $this->initializeLazyObject()->getrange(...\func_get_args()); } public function lcs($key1, $key2, $options = null): \RedisCluster|array|false|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lcs(...\func_get_args()); + return $this->initializeLazyObject()->lcs(...\func_get_args()); } public function getset($key, $value): \RedisCluster|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getset(...\func_get_args()); + return $this->initializeLazyObject()->getset(...\func_get_args()); } public function gettransferredbytes(): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->gettransferredbytes(...\func_get_args()); + return $this->initializeLazyObject()->gettransferredbytes(...\func_get_args()); } public function cleartransferredbytes(): void { - ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->cleartransferredbytes(...\func_get_args()); + $this->initializeLazyObject()->cleartransferredbytes(...\func_get_args()); } public function hdel($key, $member, ...$other_members): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hdel(...\func_get_args()); + return $this->initializeLazyObject()->hdel(...\func_get_args()); } public function hexists($key, $member): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexists(...\func_get_args()); + return $this->initializeLazyObject()->hexists(...\func_get_args()); } public function hget($key, $member): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hget(...\func_get_args()); + return $this->initializeLazyObject()->hget(...\func_get_args()); } public function hgetall($key): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetall(...\func_get_args()); + return $this->initializeLazyObject()->hgetall(...\func_get_args()); } public function hincrby($key, $member, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrby(...\func_get_args()); + return $this->initializeLazyObject()->hincrby(...\func_get_args()); } public function hincrbyfloat($key, $member, $value): \RedisCluster|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->hincrbyfloat(...\func_get_args()); } public function hkeys($key): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hkeys(...\func_get_args()); + return $this->initializeLazyObject()->hkeys(...\func_get_args()); } public function hlen($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hlen(...\func_get_args()); + return $this->initializeLazyObject()->hlen(...\func_get_args()); } public function hmget($key, $keys): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmget(...\func_get_args()); + return $this->initializeLazyObject()->hmget(...\func_get_args()); } public function hmset($key, $key_values): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmset(...\func_get_args()); + return $this->initializeLazyObject()->hmset(...\func_get_args()); } public function hscan($key, &$iterator, $pattern = null, $count = 0): array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function hrandfield($key, $options = null): \RedisCluster|array|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hrandfield(...\func_get_args()); + return $this->initializeLazyObject()->hrandfield(...\func_get_args()); } public function hset($key, $member, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hset(...\func_get_args()); + return $this->initializeLazyObject()->hset(...\func_get_args()); } public function hsetnx($key, $member, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hsetnx(...\func_get_args()); + return $this->initializeLazyObject()->hsetnx(...\func_get_args()); } public function hstrlen($key, $field): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hstrlen(...\func_get_args()); + return $this->initializeLazyObject()->hstrlen(...\func_get_args()); } public function hvals($key): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hvals(...\func_get_args()); + return $this->initializeLazyObject()->hvals(...\func_get_args()); } public function incr($key, $by = 1): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incr(...\func_get_args()); + return $this->initializeLazyObject()->incr(...\func_get_args()); } public function incrby($key, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrby(...\func_get_args()); + return $this->initializeLazyObject()->incrby(...\func_get_args()); } public function incrbyfloat($key, $value): \RedisCluster|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->incrbyfloat(...\func_get_args()); } public function info($key_or_address, ...$sections): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->info(...\func_get_args()); + return $this->initializeLazyObject()->info(...\func_get_args()); } public function keys($pattern): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->keys(...\func_get_args()); + return $this->initializeLazyObject()->keys(...\func_get_args()); } public function lastsave($key_or_address): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lastsave(...\func_get_args()); + return $this->initializeLazyObject()->lastsave(...\func_get_args()); } public function lget($key, $index): \RedisCluster|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lget(...\func_get_args()); + return $this->initializeLazyObject()->lget(...\func_get_args()); } public function lindex($key, $index): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lindex(...\func_get_args()); + return $this->initializeLazyObject()->lindex(...\func_get_args()); } public function linsert($key, $pos, $pivot, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->linsert(...\func_get_args()); + return $this->initializeLazyObject()->linsert(...\func_get_args()); } public function llen($key): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->llen(...\func_get_args()); + return $this->initializeLazyObject()->llen(...\func_get_args()); } public function lpop($key, $count = 0): \RedisCluster|array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpop(...\func_get_args()); + return $this->initializeLazyObject()->lpop(...\func_get_args()); } public function lpos($key, $value, $options = null): \Redis|array|bool|int|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpos(...\func_get_args()); + return $this->initializeLazyObject()->lpos(...\func_get_args()); } public function lpush($key, $value, ...$other_values): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpush(...\func_get_args()); + return $this->initializeLazyObject()->lpush(...\func_get_args()); } public function lpushx($key, $value): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpushx(...\func_get_args()); + return $this->initializeLazyObject()->lpushx(...\func_get_args()); } public function lrange($key, $start, $end): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrange(...\func_get_args()); + return $this->initializeLazyObject()->lrange(...\func_get_args()); } public function lrem($key, $value, $count = 0): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrem(...\func_get_args()); + return $this->initializeLazyObject()->lrem(...\func_get_args()); } public function lset($key, $index, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lset(...\func_get_args()); + return $this->initializeLazyObject()->lset(...\func_get_args()); } public function ltrim($key, $start, $end): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ltrim(...\func_get_args()); + return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public function mget($keys): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mget(...\func_get_args()); + return $this->initializeLazyObject()->mget(...\func_get_args()); } public function mset($key_values): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mset(...\func_get_args()); + return $this->initializeLazyObject()->mset(...\func_get_args()); } public function msetnx($key_values): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->msetnx(...\func_get_args()); + return $this->initializeLazyObject()->msetnx(...\func_get_args()); } public function multi($value = \Redis::MULTI): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->multi(...\func_get_args()); + return $this->initializeLazyObject()->multi(...\func_get_args()); } public function object($subcommand, $key): \RedisCluster|false|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->object(...\func_get_args()); + return $this->initializeLazyObject()->object(...\func_get_args()); } public function persist($key): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->persist(...\func_get_args()); + return $this->initializeLazyObject()->persist(...\func_get_args()); } public function pexpire($key, $timeout, $mode = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpire(...\func_get_args()); + return $this->initializeLazyObject()->pexpire(...\func_get_args()); } public function pexpireat($key, $timestamp, $mode = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpireat(...\func_get_args()); + return $this->initializeLazyObject()->pexpireat(...\func_get_args()); } public function pfadd($key, $elements): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfadd(...\func_get_args()); + return $this->initializeLazyObject()->pfadd(...\func_get_args()); } public function pfcount($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfcount(...\func_get_args()); + return $this->initializeLazyObject()->pfcount(...\func_get_args()); } public function pfmerge($key, $keys): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfmerge(...\func_get_args()); + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } public function ping($key_or_address, $message = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ping(...\func_get_args()); + return $this->initializeLazyObject()->ping(...\func_get_args()); } public function psetex($key, $timeout, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psetex(...\func_get_args()); + return $this->initializeLazyObject()->psetex(...\func_get_args()); } public function psubscribe($patterns, $callback): void { - ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psubscribe(...\func_get_args()); + $this->initializeLazyObject()->psubscribe(...\func_get_args()); } public function pttl($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pttl(...\func_get_args()); + return $this->initializeLazyObject()->pttl(...\func_get_args()); } public function publish($channel, $message): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->publish(...\func_get_args()); + return $this->initializeLazyObject()->publish(...\func_get_args()); } public function pubsub($key_or_address, ...$values): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pubsub(...\func_get_args()); + return $this->initializeLazyObject()->pubsub(...\func_get_args()); } public function punsubscribe($pattern, ...$other_patterns): array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->punsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); } public function randomkey($key_or_address): \RedisCluster|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->randomkey(...\func_get_args()); + return $this->initializeLazyObject()->randomkey(...\func_get_args()); } public function rawcommand($key_or_address, $command, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rawcommand(...\func_get_args()); + return $this->initializeLazyObject()->rawcommand(...\func_get_args()); } public function rename($key_src, $key_dst): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rename(...\func_get_args()); + return $this->initializeLazyObject()->rename(...\func_get_args()); } public function renamenx($key, $newkey): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renamenx(...\func_get_args()); + return $this->initializeLazyObject()->renamenx(...\func_get_args()); } public function restore($key, $timeout, $value, $options = null): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->restore(...\func_get_args()); + return $this->initializeLazyObject()->restore(...\func_get_args()); } public function role($key_or_address): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->role(...\func_get_args()); + return $this->initializeLazyObject()->role(...\func_get_args()); } public function rpop($key, $count = 0): \RedisCluster|array|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpop(...\func_get_args()); + return $this->initializeLazyObject()->rpop(...\func_get_args()); } public function rpoplpush($src, $dst): \RedisCluster|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); } public function rpush($key, ...$elements): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpush(...\func_get_args()); + return $this->initializeLazyObject()->rpush(...\func_get_args()); } public function rpushx($key, $value): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpushx(...\func_get_args()); + return $this->initializeLazyObject()->rpushx(...\func_get_args()); } public function sadd($key, $value, ...$other_values): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sadd(...\func_get_args()); + return $this->initializeLazyObject()->sadd(...\func_get_args()); } public function saddarray($key, $values): \RedisCluster|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->saddarray(...\func_get_args()); + return $this->initializeLazyObject()->saddarray(...\func_get_args()); } public function save($key_or_address): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->save(...\func_get_args()); + return $this->initializeLazyObject()->save(...\func_get_args()); } public function scan(&$iterator, $key_or_address, $pattern = null, $count = 0): array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scan($iterator, ...\array_slice(\func_get_args(), 1)); + return $this->initializeLazyObject()->scan($iterator, ...\array_slice(\func_get_args(), 1)); } public function scard($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scard(...\func_get_args()); + return $this->initializeLazyObject()->scard(...\func_get_args()); } public function script($key_or_address, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->script(...\func_get_args()); + return $this->initializeLazyObject()->script(...\func_get_args()); } public function sdiff($key, ...$other_keys): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiff(...\func_get_args()); + return $this->initializeLazyObject()->sdiff(...\func_get_args()); } public function sdiffstore($dst, $key, ...$other_keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->sdiffstore(...\func_get_args()); } public function set($key, $value, $options = null): \RedisCluster|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->set(...\func_get_args()); + return $this->initializeLazyObject()->set(...\func_get_args()); } public function setbit($key, $offset, $onoff): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setbit(...\func_get_args()); + return $this->initializeLazyObject()->setbit(...\func_get_args()); } public function setex($key, $expire, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setex(...\func_get_args()); + return $this->initializeLazyObject()->setex(...\func_get_args()); } public function setnx($key, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setnx(...\func_get_args()); + return $this->initializeLazyObject()->setnx(...\func_get_args()); } public function setoption($option, $value): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setoption(...\func_get_args()); + return $this->initializeLazyObject()->setoption(...\func_get_args()); } public function setrange($key, $offset, $value): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setrange(...\func_get_args()); + return $this->initializeLazyObject()->setrange(...\func_get_args()); } public function sinter($key, ...$other_keys): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinter(...\func_get_args()); + return $this->initializeLazyObject()->sinter(...\func_get_args()); } public function sintercard($keys, $limit = -1): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sintercard(...\func_get_args()); + return $this->initializeLazyObject()->sintercard(...\func_get_args()); } public function sinterstore($key, ...$other_keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinterstore(...\func_get_args()); + return $this->initializeLazyObject()->sinterstore(...\func_get_args()); } public function sismember($key, $value): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sismember(...\func_get_args()); + return $this->initializeLazyObject()->sismember(...\func_get_args()); } public function smismember($key, $member, ...$other_members): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smismember(...\func_get_args()); + return $this->initializeLazyObject()->smismember(...\func_get_args()); } public function slowlog($key_or_address, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slowlog(...\func_get_args()); + return $this->initializeLazyObject()->slowlog(...\func_get_args()); } public function smembers($key): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smembers(...\func_get_args()); + return $this->initializeLazyObject()->smembers(...\func_get_args()); } public function smove($src, $dst, $member): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smove(...\func_get_args()); + return $this->initializeLazyObject()->smove(...\func_get_args()); } public function sort($key, $options = null): \RedisCluster|array|bool|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort(...\func_get_args()); + return $this->initializeLazyObject()->sort(...\func_get_args()); } public function sort_ro($key, $options = null): \RedisCluster|array|bool|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort_ro(...\func_get_args()); + return $this->initializeLazyObject()->sort_ro(...\func_get_args()); } public function spop($key, $count = 0): \RedisCluster|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->spop(...\func_get_args()); + return $this->initializeLazyObject()->spop(...\func_get_args()); } public function srandmember($key, $count = 0): \RedisCluster|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srandmember(...\func_get_args()); + return $this->initializeLazyObject()->srandmember(...\func_get_args()); } public function srem($key, $value, ...$other_values): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srem(...\func_get_args()); + return $this->initializeLazyObject()->srem(...\func_get_args()); } public function sscan($key, &$iterator, $pattern = null, $count = 0): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function strlen($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->strlen(...\func_get_args()); + return $this->initializeLazyObject()->strlen(...\func_get_args()); } public function subscribe($channels, $cb): void { - ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->subscribe(...\func_get_args()); + $this->initializeLazyObject()->subscribe(...\func_get_args()); } public function sunion($key, ...$other_keys): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunion(...\func_get_args()); + return $this->initializeLazyObject()->sunion(...\func_get_args()); } public function sunionstore($dst, $key, ...$other_keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunionstore(...\func_get_args()); + return $this->initializeLazyObject()->sunionstore(...\func_get_args()); } public function time($key_or_address): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->time(...\func_get_args()); + return $this->initializeLazyObject()->time(...\func_get_args()); } public function ttl($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ttl(...\func_get_args()); + return $this->initializeLazyObject()->ttl(...\func_get_args()); } public function type($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->type(...\func_get_args()); + return $this->initializeLazyObject()->type(...\func_get_args()); } public function unsubscribe($channels): array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); } public function unlink($key, ...$other_keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unlink(...\func_get_args()); + return $this->initializeLazyObject()->unlink(...\func_get_args()); } public function unwatch(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unwatch(...\func_get_args()); + return $this->initializeLazyObject()->unwatch(...\func_get_args()); } public function watch($key, ...$other_keys): \RedisCluster|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->watch(...\func_get_args()); + return $this->initializeLazyObject()->watch(...\func_get_args()); } public function xack($key, $group, $ids): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xack(...\func_get_args()); + return $this->initializeLazyObject()->xack(...\func_get_args()); } public function xadd($key, $id, $values, $maxlen = 0, $approx = false): \RedisCluster|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xadd(...\func_get_args()); + return $this->initializeLazyObject()->xadd(...\func_get_args()); } public function xclaim($key, $group, $consumer, $min_iddle, $ids, $options): \RedisCluster|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xclaim(...\func_get_args()); + return $this->initializeLazyObject()->xclaim(...\func_get_args()); } public function xdel($key, $ids): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xdel(...\func_get_args()); + return $this->initializeLazyObject()->xdel(...\func_get_args()); } public function xgroup($operation, $key = null, $group = null, $id_or_consumer = null, $mkstream = false, $entries_read = -2): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xgroup(...\func_get_args()); + return $this->initializeLazyObject()->xgroup(...\func_get_args()); } public function xautoclaim($key, $group, $consumer, $min_idle, $start, $count = -1, $justid = false): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xautoclaim(...\func_get_args()); + return $this->initializeLazyObject()->xautoclaim(...\func_get_args()); } public function xinfo($operation, $arg1 = null, $arg2 = null, $count = -1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xinfo(...\func_get_args()); + return $this->initializeLazyObject()->xinfo(...\func_get_args()); } public function xlen($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xlen(...\func_get_args()); + return $this->initializeLazyObject()->xlen(...\func_get_args()); } public function xpending($key, $group, $start = null, $end = null, $count = -1, $consumer = null): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xpending(...\func_get_args()); + return $this->initializeLazyObject()->xpending(...\func_get_args()); } public function xrange($key, $start, $end, $count = -1): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrange(...\func_get_args()); + return $this->initializeLazyObject()->xrange(...\func_get_args()); } public function xread($streams, $count = -1, $block = -1): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xread(...\func_get_args()); + return $this->initializeLazyObject()->xread(...\func_get_args()); } public function xreadgroup($group, $consumer, $streams, $count = 1, $block = 1): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xreadgroup(...\func_get_args()); + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } public function xrevrange($key, $start, $end, $count = -1): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrevrange(...\func_get_args()); + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } public function xtrim($key, $maxlen, $approx = false, $minid = false, $limit = -1): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xtrim(...\func_get_args()); + return $this->initializeLazyObject()->xtrim(...\func_get_args()); } public function zadd($key, $score_or_options, ...$more_scores_and_mems): \RedisCluster|false|float|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zadd(...\func_get_args()); + return $this->initializeLazyObject()->zadd(...\func_get_args()); } public function zcard($key): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcard(...\func_get_args()); + return $this->initializeLazyObject()->zcard(...\func_get_args()); } public function zcount($key, $start, $end): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcount(...\func_get_args()); + return $this->initializeLazyObject()->zcount(...\func_get_args()); } public function zincrby($key, $value, $member): \RedisCluster|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zincrby(...\func_get_args()); + return $this->initializeLazyObject()->zincrby(...\func_get_args()); } public function zinterstore($dst, $keys, $weights = null, $aggregate = null): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinterstore(...\func_get_args()); + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } public function zintercard($keys, $limit = -1): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zintercard(...\func_get_args()); + return $this->initializeLazyObject()->zintercard(...\func_get_args()); } public function zlexcount($key, $min, $max): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zlexcount(...\func_get_args()); + return $this->initializeLazyObject()->zlexcount(...\func_get_args()); } public function zpopmax($key, $value = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmax(...\func_get_args()); + return $this->initializeLazyObject()->zpopmax(...\func_get_args()); } public function zpopmin($key, $value = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmin(...\func_get_args()); + return $this->initializeLazyObject()->zpopmin(...\func_get_args()); } public function zrange($key, $start, $end, $options = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrange(...\func_get_args()); + return $this->initializeLazyObject()->zrange(...\func_get_args()); } public function zrangestore($dstkey, $srckey, $start, $end, $options = null): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangestore(...\func_get_args()); + return $this->initializeLazyObject()->zrangestore(...\func_get_args()); } public function zrandmember($key, $options = null): \RedisCluster|array|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrandmember(...\func_get_args()); + return $this->initializeLazyObject()->zrandmember(...\func_get_args()); } public function zrangebylex($key, $min, $max, $offset = -1, $count = -1): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrangebylex(...\func_get_args()); } public function zrangebyscore($key, $start, $end, $options = []): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrangebyscore(...\func_get_args()); } public function zrank($key, $member): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrank(...\func_get_args()); + return $this->initializeLazyObject()->zrank(...\func_get_args()); } public function zrem($key, $value, ...$other_values): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrem(...\func_get_args()); + return $this->initializeLazyObject()->zrem(...\func_get_args()); } public function zremrangebylex($key, $min, $max): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebylex(...\func_get_args()); } public function zremrangebyrank($key, $min, $max): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyrank(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyrank(...\func_get_args()); } public function zremrangebyscore($key, $min, $max): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyscore(...\func_get_args()); } public function zrevrange($key, $min, $max, $options = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrange(...\func_get_args()); + return $this->initializeLazyObject()->zrevrange(...\func_get_args()); } public function zrevrangebylex($key, $min, $max, $options = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebylex(...\func_get_args()); } public function zrevrangebyscore($key, $min, $max, $options = null): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebyscore(...\func_get_args()); } public function zrevrank($key, $member): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrank(...\func_get_args()); + return $this->initializeLazyObject()->zrevrank(...\func_get_args()); } public function zscan($key, &$iterator, $pattern = null, $count = 0): \RedisCluster|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function zscore($key, $member): \RedisCluster|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscore(...\func_get_args()); + return $this->initializeLazyObject()->zscore(...\func_get_args()); } public function zmscore($key, $member, ...$other_members): \Redis|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zmscore(...\func_get_args()); + return $this->initializeLazyObject()->zmscore(...\func_get_args()); } public function zunionstore($dst, $keys, $weights = null, $aggregate = null): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunionstore(...\func_get_args()); + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } public function zinter($keys, $weights = null, $options = null): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinter(...\func_get_args()); + return $this->initializeLazyObject()->zinter(...\func_get_args()); } public function zdiffstore($dst, $keys): \RedisCluster|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->zdiffstore(...\func_get_args()); } public function zunion($keys, $weights = null, $options = null): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunion(...\func_get_args()); + return $this->initializeLazyObject()->zunion(...\func_get_args()); } public function zdiff($keys, $options = null): \RedisCluster|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiff(...\func_get_args()); + return $this->initializeLazyObject()->zdiff(...\func_get_args()); } } diff --git a/Traits/RedisProxyTrait.php b/Traits/RedisProxyTrait.php new file mode 100644 index 00000000..c138969b --- /dev/null +++ b/Traits/RedisProxyTrait.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +trait RedisProxyTrait +{ + private \Closure $initializer; + private ?parent $realInstance = null; + + public static function createLazyProxy(\Closure $initializer, ?self $instance = null): static + { + $instance ??= (new \ReflectionClass(static::class))->newInstanceWithoutConstructor(); + $instance->realInstance = null; + $instance->initializer = $initializer; + + return $instance; + } + + public function isLazyObjectInitialized(bool $partial = false): bool + { + return isset($this->realInstance); + } + + public function initializeLazyObject(): object + { + return $this->realInstance ??= ($this->initializer)(); + } + + public function resetLazyObject(): bool + { + $this->realInstance = null; + + return true; + } + + public function __destruct() + { + } +} diff --git a/Traits/RelayProxy.php b/Traits/RelayProxy.php index ac839dfd..e63af0d7 100644 --- a/Traits/RelayProxy.php +++ b/Traits/RelayProxy.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Cache\Traits; use Symfony\Component\VarExporter\LazyObjectInterface; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Contracts\Service\ResetInterface; // Help opcache.preload discover always-needed symbols @@ -25,1299 +24,1297 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class RelayProxy extends \Relay\Relay implements ResetInterface, LazyObjectInterface { - use LazyProxyTrait { + use RedisProxyTrait { resetLazyObject as reset; } - private const LAZY_OBJECT_PROPERTY_SCOPES = []; - public function __construct($host = null, $port = 6379, $connect_timeout = 0.0, $command_timeout = 0.0, #[\SensitiveParameter] $context = [], $database = 0) { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->__construct(...\func_get_args()); + $this->initializeLazyObject()->__construct(...\func_get_args()); } public function connect($host, $port = 6379, $timeout = 0.0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0.0, #[\SensitiveParameter] $context = [], $database = 0): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->connect(...\func_get_args()); + return $this->initializeLazyObject()->connect(...\func_get_args()); } public function pconnect($host, $port = 6379, $timeout = 0.0, $persistent_id = null, $retry_interval = 0, $read_timeout = 0.0, #[\SensitiveParameter] $context = [], $database = 0): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pconnect(...\func_get_args()); + return $this->initializeLazyObject()->pconnect(...\func_get_args()); } public function close(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->close(...\func_get_args()); + return $this->initializeLazyObject()->close(...\func_get_args()); } public function pclose(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pclose(...\func_get_args()); + return $this->initializeLazyObject()->pclose(...\func_get_args()); } public function listen($callback): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->listen(...\func_get_args()); + return $this->initializeLazyObject()->listen(...\func_get_args()); } public function onFlushed($callback): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->onFlushed(...\func_get_args()); + return $this->initializeLazyObject()->onFlushed(...\func_get_args()); } public function onInvalidated($callback, $pattern = null): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->onInvalidated(...\func_get_args()); + return $this->initializeLazyObject()->onInvalidated(...\func_get_args()); } public function dispatchEvents(): false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dispatchEvents(...\func_get_args()); + return $this->initializeLazyObject()->dispatchEvents(...\func_get_args()); } public function getOption($option): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getOption(...\func_get_args()); + return $this->initializeLazyObject()->getOption(...\func_get_args()); } public function option($option, $value = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->option(...\func_get_args()); + return $this->initializeLazyObject()->option(...\func_get_args()); } public function setOption($option, $value): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setOption(...\func_get_args()); + return $this->initializeLazyObject()->setOption(...\func_get_args()); } public function addIgnorePatterns(...$pattern): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->addIgnorePatterns(...\func_get_args()); + return $this->initializeLazyObject()->addIgnorePatterns(...\func_get_args()); } public function addAllowPatterns(...$pattern): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->addAllowPatterns(...\func_get_args()); + return $this->initializeLazyObject()->addAllowPatterns(...\func_get_args()); } public function getTimeout(): false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getTimeout(...\func_get_args()); } public function timeout(): false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->timeout(...\func_get_args()); + return $this->initializeLazyObject()->timeout(...\func_get_args()); } public function getReadTimeout(): false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getReadTimeout(...\func_get_args()); + return $this->initializeLazyObject()->getReadTimeout(...\func_get_args()); } public function readTimeout(): false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->readTimeout(...\func_get_args()); + return $this->initializeLazyObject()->readTimeout(...\func_get_args()); } public function getBytes(): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getBytes(...\func_get_args()); + return $this->initializeLazyObject()->getBytes(...\func_get_args()); } public function bytes(): array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bytes(...\func_get_args()); + return $this->initializeLazyObject()->bytes(...\func_get_args()); } public function getHost(): false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getHost(...\func_get_args()); + return $this->initializeLazyObject()->getHost(...\func_get_args()); } public function isConnected(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->isConnected(...\func_get_args()); + return $this->initializeLazyObject()->isConnected(...\func_get_args()); } public function getPort(): false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPort(...\func_get_args()); + return $this->initializeLazyObject()->getPort(...\func_get_args()); } public function getAuth(): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getAuth(...\func_get_args()); + return $this->initializeLazyObject()->getAuth(...\func_get_args()); } public function getDbNum(): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getDbNum(...\func_get_args()); + return $this->initializeLazyObject()->getDbNum(...\func_get_args()); } public function _serialize($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_serialize(...\func_get_args()); + return $this->initializeLazyObject()->_serialize(...\func_get_args()); } public function _unserialize($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unserialize(...\func_get_args()); + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); } public function _compress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_compress(...\func_get_args()); + return $this->initializeLazyObject()->_compress(...\func_get_args()); } public function _uncompress($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_uncompress(...\func_get_args()); + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); } public function _pack($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_pack(...\func_get_args()); + return $this->initializeLazyObject()->_pack(...\func_get_args()); } public function _unpack($value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_unpack(...\func_get_args()); + return $this->initializeLazyObject()->_unpack(...\func_get_args()); } public function _prefix($value): string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_prefix(...\func_get_args()); + return $this->initializeLazyObject()->_prefix(...\func_get_args()); } public function getLastError(): ?string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getLastError(...\func_get_args()); + return $this->initializeLazyObject()->getLastError(...\func_get_args()); } public function clearLastError(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearLastError(...\func_get_args()); + return $this->initializeLazyObject()->clearLastError(...\func_get_args()); } public function endpointId(): false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->endpointId(...\func_get_args()); + return $this->initializeLazyObject()->endpointId(...\func_get_args()); } public function getPersistentID(): false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getPersistentID(...\func_get_args()); + return $this->initializeLazyObject()->getPersistentID(...\func_get_args()); } public function socketId(): false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->socketId(...\func_get_args()); + return $this->initializeLazyObject()->socketId(...\func_get_args()); } public function rawCommand($cmd, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rawCommand(...\func_get_args()); + return $this->initializeLazyObject()->rawCommand(...\func_get_args()); } public function select($db): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->select(...\func_get_args()); + return $this->initializeLazyObject()->select(...\func_get_args()); } public function auth(#[\SensitiveParameter] $auth): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->auth(...\func_get_args()); + return $this->initializeLazyObject()->auth(...\func_get_args()); } public function info(...$sections): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->info(...\func_get_args()); + return $this->initializeLazyObject()->info(...\func_get_args()); } public function flushdb($sync = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushdb(...\func_get_args()); + return $this->initializeLazyObject()->flushdb(...\func_get_args()); } public function flushall($sync = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->flushall(...\func_get_args()); + return $this->initializeLazyObject()->flushall(...\func_get_args()); } public function fcall($name, $keys = [], $argv = [], $handler = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->fcall(...\func_get_args()); + return $this->initializeLazyObject()->fcall(...\func_get_args()); } public function fcall_ro($name, $keys = [], $argv = [], $handler = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->fcall_ro(...\func_get_args()); + return $this->initializeLazyObject()->fcall_ro(...\func_get_args()); } public function function($op, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->function(...\func_get_args()); + return $this->initializeLazyObject()->function(...\func_get_args()); } public function dbsize(): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dbsize(...\func_get_args()); + return $this->initializeLazyObject()->dbsize(...\func_get_args()); } public function dump($key): \Relay\Relay|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->dump(...\func_get_args()); + return $this->initializeLazyObject()->dump(...\func_get_args()); } public function replicaof($host = null, $port = 0): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->replicaof(...\func_get_args()); + return $this->initializeLazyObject()->replicaof(...\func_get_args()); } public function waitaof($numlocal, $numremote, $timeout): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->waitaof(...\func_get_args()); + return $this->initializeLazyObject()->waitaof(...\func_get_args()); } public function restore($key, $ttl, $value, $options = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->restore(...\func_get_args()); + return $this->initializeLazyObject()->restore(...\func_get_args()); } public function migrate($host, $port, $key, $dstdb, $timeout, $copy = false, $replace = false, #[\SensitiveParameter] $credentials = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->migrate(...\func_get_args()); + return $this->initializeLazyObject()->migrate(...\func_get_args()); } public function copy($src, $dst, $options = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args()); + return $this->initializeLazyObject()->copy(...\func_get_args()); } public function echo($arg): \Relay\Relay|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->echo(...\func_get_args()); + return $this->initializeLazyObject()->echo(...\func_get_args()); } public function ping($arg = null): \Relay\Relay|bool|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ping(...\func_get_args()); + return $this->initializeLazyObject()->ping(...\func_get_args()); } public function idleTime(): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->idleTime(...\func_get_args()); + return $this->initializeLazyObject()->idleTime(...\func_get_args()); } public function randomkey(): \Relay\Relay|bool|null|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->randomkey(...\func_get_args()); + return $this->initializeLazyObject()->randomkey(...\func_get_args()); } public function time(): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->time(...\func_get_args()); + return $this->initializeLazyObject()->time(...\func_get_args()); } public function bgrewriteaof(): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgrewriteaof(...\func_get_args()); + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } public function lastsave(): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lastsave(...\func_get_args()); + return $this->initializeLazyObject()->lastsave(...\func_get_args()); } public function lcs($key1, $key2, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lcs(...\func_get_args()); + return $this->initializeLazyObject()->lcs(...\func_get_args()); } public function bgsave($schedule = false): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bgsave(...\func_get_args()); + return $this->initializeLazyObject()->bgsave(...\func_get_args()); } public function save(): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->save(...\func_get_args()); + return $this->initializeLazyObject()->save(...\func_get_args()); } public function role(): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->role(...\func_get_args()); + return $this->initializeLazyObject()->role(...\func_get_args()); } public function ttl($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ttl(...\func_get_args()); + return $this->initializeLazyObject()->ttl(...\func_get_args()); } public function pttl($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pttl(...\func_get_args()); + return $this->initializeLazyObject()->pttl(...\func_get_args()); } public function exists(...$keys): \Relay\Relay|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exists(...\func_get_args()); + return $this->initializeLazyObject()->exists(...\func_get_args()); } public function eval($script, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval(...\func_get_args()); + return $this->initializeLazyObject()->eval(...\func_get_args()); } public function eval_ro($script, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->eval_ro(...\func_get_args()); + return $this->initializeLazyObject()->eval_ro(...\func_get_args()); } public function evalsha($sha, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha(...\func_get_args()); + return $this->initializeLazyObject()->evalsha(...\func_get_args()); } public function evalsha_ro($sha, $args = [], $num_keys = 0): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->evalsha_ro(...\func_get_args()); + return $this->initializeLazyObject()->evalsha_ro(...\func_get_args()); } public function client($operation, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->client(...\func_get_args()); + return $this->initializeLazyObject()->client(...\func_get_args()); } public function geoadd($key, $lng, $lat, $member, ...$other_triples_and_options): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geoadd(...\func_get_args()); + return $this->initializeLazyObject()->geoadd(...\func_get_args()); } public function geodist($key, $src, $dst, $unit = null): \Relay\Relay|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geodist(...\func_get_args()); + return $this->initializeLazyObject()->geodist(...\func_get_args()); } public function geohash($key, $member, ...$other_members): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geohash(...\func_get_args()); + return $this->initializeLazyObject()->geohash(...\func_get_args()); } public function georadius($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius(...\func_get_args()); + return $this->initializeLazyObject()->georadius(...\func_get_args()); } public function georadiusbymember($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); } public function georadiusbymember_ro($key, $member, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadiusbymember_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); } public function georadius_ro($key, $lng, $lat, $radius, $unit, $options = []): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->georadius_ro(...\func_get_args()); + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } public function geosearch($key, $position, $shape, $unit, $options = []): \Relay\Relay|array { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearch(...\func_get_args()); + return $this->initializeLazyObject()->geosearch(...\func_get_args()); } public function geosearchstore($dst, $src, $position, $shape, $unit, $options = []): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geosearchstore(...\func_get_args()); + return $this->initializeLazyObject()->geosearchstore(...\func_get_args()); } public function get($key): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->get(...\func_get_args()); + return $this->initializeLazyObject()->get(...\func_get_args()); } public function getset($key, $value): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getset(...\func_get_args()); + return $this->initializeLazyObject()->getset(...\func_get_args()); } public function getrange($key, $start, $end): \Relay\Relay|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getrange(...\func_get_args()); + return $this->initializeLazyObject()->getrange(...\func_get_args()); } public function setrange($key, $start, $value): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setrange(...\func_get_args()); + return $this->initializeLazyObject()->setrange(...\func_get_args()); } public function getbit($key, $pos): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getbit(...\func_get_args()); + return $this->initializeLazyObject()->getbit(...\func_get_args()); } public function bitcount($key, $start = 0, $end = -1, $by_bit = false): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitcount(...\func_get_args()); + return $this->initializeLazyObject()->bitcount(...\func_get_args()); } public function bitfield($key, ...$args): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitfield(...\func_get_args()); + return $this->initializeLazyObject()->bitfield(...\func_get_args()); } public function config($operation, $key = null, $value = null): \Relay\Relay|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->config(...\func_get_args()); + return $this->initializeLazyObject()->config(...\func_get_args()); } public function command(...$args): \Relay\Relay|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->command(...\func_get_args()); + return $this->initializeLazyObject()->command(...\func_get_args()); } public function bitop($operation, $dstkey, $srckey, ...$other_keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitop(...\func_get_args()); + return $this->initializeLazyObject()->bitop(...\func_get_args()); } public function bitpos($key, $bit, $start = null, $end = null, $bybit = false): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bitpos(...\func_get_args()); + return $this->initializeLazyObject()->bitpos(...\func_get_args()); } public function setbit($key, $pos, $val): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setbit(...\func_get_args()); + return $this->initializeLazyObject()->setbit(...\func_get_args()); } public function acl($cmd, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->acl(...\func_get_args()); + return $this->initializeLazyObject()->acl(...\func_get_args()); } public function append($key, $value): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->append(...\func_get_args()); + return $this->initializeLazyObject()->append(...\func_get_args()); } public function set($key, $value, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->set(...\func_get_args()); + return $this->initializeLazyObject()->set(...\func_get_args()); } public function getex($key, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getex(...\func_get_args()); + return $this->initializeLazyObject()->getex(...\func_get_args()); } public function getdel($key): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getdel(...\func_get_args()); + return $this->initializeLazyObject()->getdel(...\func_get_args()); } public function setex($key, $seconds, $value): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setex(...\func_get_args()); + return $this->initializeLazyObject()->setex(...\func_get_args()); } public function pfadd($key, $elements): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfadd(...\func_get_args()); + return $this->initializeLazyObject()->pfadd(...\func_get_args()); } public function pfcount($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfcount(...\func_get_args()); + return $this->initializeLazyObject()->pfcount(...\func_get_args()); } public function pfmerge($dst, $srckeys): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pfmerge(...\func_get_args()); + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } public function psetex($key, $milliseconds, $value): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psetex(...\func_get_args()); + return $this->initializeLazyObject()->psetex(...\func_get_args()); } public function publish($channel, $message): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->publish(...\func_get_args()); + return $this->initializeLazyObject()->publish(...\func_get_args()); } public function pubsub($operation, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pubsub(...\func_get_args()); + return $this->initializeLazyObject()->pubsub(...\func_get_args()); } public function spublish($channel, $message): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->spublish(...\func_get_args()); + return $this->initializeLazyObject()->spublish(...\func_get_args()); } public function setnx($key, $value): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->setnx(...\func_get_args()); + return $this->initializeLazyObject()->setnx(...\func_get_args()); } public function mget($keys): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mget(...\func_get_args()); + return $this->initializeLazyObject()->mget(...\func_get_args()); } public function move($key, $db): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->move(...\func_get_args()); + return $this->initializeLazyObject()->move(...\func_get_args()); } public function mset($kvals): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->mset(...\func_get_args()); + return $this->initializeLazyObject()->mset(...\func_get_args()); } public function msetnx($kvals): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->msetnx(...\func_get_args()); + return $this->initializeLazyObject()->msetnx(...\func_get_args()); } public function rename($key, $newkey): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rename(...\func_get_args()); + return $this->initializeLazyObject()->rename(...\func_get_args()); } public function renamenx($key, $newkey): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->renamenx(...\func_get_args()); + return $this->initializeLazyObject()->renamenx(...\func_get_args()); } public function del(...$keys): \Relay\Relay|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->del(...\func_get_args()); + return $this->initializeLazyObject()->del(...\func_get_args()); } public function unlink(...$keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unlink(...\func_get_args()); + return $this->initializeLazyObject()->unlink(...\func_get_args()); } public function expire($key, $seconds, $mode = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expire(...\func_get_args()); + return $this->initializeLazyObject()->expire(...\func_get_args()); } public function pexpire($key, $milliseconds): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpire(...\func_get_args()); + return $this->initializeLazyObject()->pexpire(...\func_get_args()); } public function expireat($key, $timestamp): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expireat(...\func_get_args()); + return $this->initializeLazyObject()->expireat(...\func_get_args()); } public function expiretime($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expiretime(...\func_get_args()); + return $this->initializeLazyObject()->expiretime(...\func_get_args()); } public function pexpireat($key, $timestamp_ms): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpireat(...\func_get_args()); + return $this->initializeLazyObject()->pexpireat(...\func_get_args()); } public function pexpiretime($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pexpiretime(...\func_get_args()); + return $this->initializeLazyObject()->pexpiretime(...\func_get_args()); } public function persist($key): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->persist(...\func_get_args()); + return $this->initializeLazyObject()->persist(...\func_get_args()); } public function type($key): \Relay\Relay|bool|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->type(...\func_get_args()); + return $this->initializeLazyObject()->type(...\func_get_args()); } public function lmove($srckey, $dstkey, $srcpos, $dstpos): \Relay\Relay|false|null|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lmove(...\func_get_args()); + return $this->initializeLazyObject()->lmove(...\func_get_args()); } public function blmove($srckey, $dstkey, $srcpos, $dstpos, $timeout): \Relay\Relay|false|null|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmove(...\func_get_args()); + return $this->initializeLazyObject()->blmove(...\func_get_args()); } public function lrange($key, $start, $stop): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrange(...\func_get_args()); + return $this->initializeLazyObject()->lrange(...\func_get_args()); } public function lpush($key, $mem, ...$mems): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpush(...\func_get_args()); + return $this->initializeLazyObject()->lpush(...\func_get_args()); } public function rpush($key, $mem, ...$mems): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpush(...\func_get_args()); + return $this->initializeLazyObject()->rpush(...\func_get_args()); } public function lpushx($key, $mem, ...$mems): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpushx(...\func_get_args()); + return $this->initializeLazyObject()->lpushx(...\func_get_args()); } public function rpushx($key, $mem, ...$mems): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpushx(...\func_get_args()); + return $this->initializeLazyObject()->rpushx(...\func_get_args()); } public function lset($key, $index, $mem): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lset(...\func_get_args()); + return $this->initializeLazyObject()->lset(...\func_get_args()); } public function lpop($key, $count = 1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpop(...\func_get_args()); + return $this->initializeLazyObject()->lpop(...\func_get_args()); } public function lpos($key, $value, $options = null): \Relay\Relay|array|false|int|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lpos(...\func_get_args()); + return $this->initializeLazyObject()->lpos(...\func_get_args()); } public function rpop($key, $count = 1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpop(...\func_get_args()); + return $this->initializeLazyObject()->rpop(...\func_get_args()); } public function rpoplpush($source, $dest): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->rpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); } public function brpoplpush($source, $dest, $timeout): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpoplpush(...\func_get_args()); + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } public function blpop($key, $timeout_or_key, ...$extra_args): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blpop(...\func_get_args()); + return $this->initializeLazyObject()->blpop(...\func_get_args()); } public function blmpop($timeout, $keys, $from, $count = 1): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->blmpop(...\func_get_args()); + return $this->initializeLazyObject()->blmpop(...\func_get_args()); } public function bzmpop($timeout, $keys, $from, $count = 1): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzmpop(...\func_get_args()); + return $this->initializeLazyObject()->bzmpop(...\func_get_args()); } public function lmpop($keys, $from, $count = 1): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lmpop(...\func_get_args()); + return $this->initializeLazyObject()->lmpop(...\func_get_args()); } public function zmpop($keys, $from, $count = 1): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zmpop(...\func_get_args()); + return $this->initializeLazyObject()->zmpop(...\func_get_args()); } public function brpop($key, $timeout_or_key, ...$extra_args): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->brpop(...\func_get_args()); + return $this->initializeLazyObject()->brpop(...\func_get_args()); } public function bzpopmax($key, $timeout_or_key, ...$extra_args): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmax(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmax(...\func_get_args()); } public function bzpopmin($key, $timeout_or_key, ...$extra_args): \Relay\Relay|array|false|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->bzpopmin(...\func_get_args()); + return $this->initializeLazyObject()->bzpopmin(...\func_get_args()); } public function object($op, $key): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->object(...\func_get_args()); + return $this->initializeLazyObject()->object(...\func_get_args()); } public function geopos($key, ...$members): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->geopos(...\func_get_args()); + return $this->initializeLazyObject()->geopos(...\func_get_args()); } public function lrem($key, $mem, $count = 0): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lrem(...\func_get_args()); + return $this->initializeLazyObject()->lrem(...\func_get_args()); } public function lindex($key, $index): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->lindex(...\func_get_args()); + return $this->initializeLazyObject()->lindex(...\func_get_args()); } public function linsert($key, $op, $pivot, $element): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->linsert(...\func_get_args()); + return $this->initializeLazyObject()->linsert(...\func_get_args()); } public function ltrim($key, $start, $end): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ltrim(...\func_get_args()); + return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public function hget($hash, $member): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hget(...\func_get_args()); + return $this->initializeLazyObject()->hget(...\func_get_args()); } public function hstrlen($hash, $member): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hstrlen(...\func_get_args()); + return $this->initializeLazyObject()->hstrlen(...\func_get_args()); } public function hgetall($hash): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetall(...\func_get_args()); + return $this->initializeLazyObject()->hgetall(...\func_get_args()); } public function hkeys($hash): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hkeys(...\func_get_args()); + return $this->initializeLazyObject()->hkeys(...\func_get_args()); } public function hvals($hash): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hvals(...\func_get_args()); + return $this->initializeLazyObject()->hvals(...\func_get_args()); } public function hmget($hash, $members): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmget(...\func_get_args()); + return $this->initializeLazyObject()->hmget(...\func_get_args()); } public function hrandfield($hash, $options = null): \Relay\Relay|array|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hrandfield(...\func_get_args()); + return $this->initializeLazyObject()->hrandfield(...\func_get_args()); } public function hmset($hash, $members): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hmset(...\func_get_args()); + return $this->initializeLazyObject()->hmset(...\func_get_args()); } public function hexists($hash, $member): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexists(...\func_get_args()); + return $this->initializeLazyObject()->hexists(...\func_get_args()); } public function hsetnx($hash, $member, $value): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hsetnx(...\func_get_args()); + return $this->initializeLazyObject()->hsetnx(...\func_get_args()); } public function hset($key, $mem, $val, ...$kvals): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hset(...\func_get_args()); + return $this->initializeLazyObject()->hset(...\func_get_args()); } public function hdel($key, $mem, ...$mems): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hdel(...\func_get_args()); + return $this->initializeLazyObject()->hdel(...\func_get_args()); } public function hincrby($key, $mem, $value): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrby(...\func_get_args()); + return $this->initializeLazyObject()->hincrby(...\func_get_args()); } public function hincrbyfloat($key, $mem, $value): \Relay\Relay|bool|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hincrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->hincrbyfloat(...\func_get_args()); } public function incr($key, $by = 1): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incr(...\func_get_args()); + return $this->initializeLazyObject()->incr(...\func_get_args()); } public function decr($key, $by = 1): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decr(...\func_get_args()); + return $this->initializeLazyObject()->decr(...\func_get_args()); } public function incrby($key, $value): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrby(...\func_get_args()); + return $this->initializeLazyObject()->incrby(...\func_get_args()); } public function decrby($key, $value): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->decrby(...\func_get_args()); + return $this->initializeLazyObject()->decrby(...\func_get_args()); } public function incrbyfloat($key, $value): \Relay\Relay|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->incrbyfloat(...\func_get_args()); + return $this->initializeLazyObject()->incrbyfloat(...\func_get_args()); } public function sdiff($key, ...$other_keys): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiff(...\func_get_args()); + return $this->initializeLazyObject()->sdiff(...\func_get_args()); } public function sdiffstore($key, ...$other_keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->sdiffstore(...\func_get_args()); } public function sinter($key, ...$other_keys): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinter(...\func_get_args()); + return $this->initializeLazyObject()->sinter(...\func_get_args()); } public function sintercard($keys, $limit = -1): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sintercard(...\func_get_args()); + return $this->initializeLazyObject()->sintercard(...\func_get_args()); } public function sinterstore($key, ...$other_keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sinterstore(...\func_get_args()); + return $this->initializeLazyObject()->sinterstore(...\func_get_args()); } public function sunion($key, ...$other_keys): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunion(...\func_get_args()); + return $this->initializeLazyObject()->sunion(...\func_get_args()); } public function sunionstore($key, ...$other_keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunionstore(...\func_get_args()); + return $this->initializeLazyObject()->sunionstore(...\func_get_args()); } public function subscribe($channels, $callback): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->subscribe(...\func_get_args()); + return $this->initializeLazyObject()->subscribe(...\func_get_args()); } public function unsubscribe($channels = []): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); } public function psubscribe($patterns, $callback): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->psubscribe(...\func_get_args()); + return $this->initializeLazyObject()->psubscribe(...\func_get_args()); } public function punsubscribe($patterns = []): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->punsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); } public function ssubscribe($channels, $callback): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->ssubscribe(...\func_get_args()); + return $this->initializeLazyObject()->ssubscribe(...\func_get_args()); } public function sunsubscribe($channels = []): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sunsubscribe(...\func_get_args()); + return $this->initializeLazyObject()->sunsubscribe(...\func_get_args()); } public function touch($key_or_array, ...$more_keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->touch(...\func_get_args()); + return $this->initializeLazyObject()->touch(...\func_get_args()); } public function pipeline(): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->pipeline(...\func_get_args()); + return $this->initializeLazyObject()->pipeline(...\func_get_args()); } public function multi($mode = 0): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->multi(...\func_get_args()); + return $this->initializeLazyObject()->multi(...\func_get_args()); } public function exec(): \Relay\Relay|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->exec(...\func_get_args()); + return $this->initializeLazyObject()->exec(...\func_get_args()); } public function wait($replicas, $timeout): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->wait(...\func_get_args()); + return $this->initializeLazyObject()->wait(...\func_get_args()); } public function watch($key, ...$other_keys): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->watch(...\func_get_args()); + return $this->initializeLazyObject()->watch(...\func_get_args()); } public function unwatch(): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->unwatch(...\func_get_args()); + return $this->initializeLazyObject()->unwatch(...\func_get_args()); } public function discard(): bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->discard(...\func_get_args()); + return $this->initializeLazyObject()->discard(...\func_get_args()); } public function getMode($masked = false): int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getMode(...\func_get_args()); + return $this->initializeLazyObject()->getMode(...\func_get_args()); } public function clearBytes(): void { - ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->clearBytes(...\func_get_args()); + $this->initializeLazyObject()->clearBytes(...\func_get_args()); } public function scan(&$iterator, $match = null, $count = 0, $type = null): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scan($iterator, ...\array_slice(\func_get_args(), 1)); + return $this->initializeLazyObject()->scan($iterator, ...\array_slice(\func_get_args(), 1)); } public function hscan($key, &$iterator, $match = null, $count = 0): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function sscan($key, &$iterator, $match = null, $count = 0): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function zscan($key, &$iterator, $match = null, $count = 0): array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + return $this->initializeLazyObject()->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } public function keys($pattern): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->keys(...\func_get_args()); + return $this->initializeLazyObject()->keys(...\func_get_args()); } public function slowlog($operation, ...$extra_args): \Relay\Relay|array|bool|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->slowlog(...\func_get_args()); + return $this->initializeLazyObject()->slowlog(...\func_get_args()); } public function smembers($set): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smembers(...\func_get_args()); + return $this->initializeLazyObject()->smembers(...\func_get_args()); } public function sismember($set, $member): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sismember(...\func_get_args()); + return $this->initializeLazyObject()->sismember(...\func_get_args()); } public function smismember($set, ...$members): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smismember(...\func_get_args()); + return $this->initializeLazyObject()->smismember(...\func_get_args()); } public function srem($set, $member, ...$members): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srem(...\func_get_args()); + return $this->initializeLazyObject()->srem(...\func_get_args()); } public function sadd($set, $member, ...$members): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sadd(...\func_get_args()); + return $this->initializeLazyObject()->sadd(...\func_get_args()); } public function sort($key, $options = []): \Relay\Relay|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort(...\func_get_args()); + return $this->initializeLazyObject()->sort(...\func_get_args()); } public function sort_ro($key, $options = []): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->sort_ro(...\func_get_args()); + return $this->initializeLazyObject()->sort_ro(...\func_get_args()); } public function smove($srcset, $dstset, $member): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->smove(...\func_get_args()); + return $this->initializeLazyObject()->smove(...\func_get_args()); } public function spop($set, $count = 1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->spop(...\func_get_args()); + return $this->initializeLazyObject()->spop(...\func_get_args()); } public function srandmember($set, $count = 1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->srandmember(...\func_get_args()); + return $this->initializeLazyObject()->srandmember(...\func_get_args()); } public function scard($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->scard(...\func_get_args()); + return $this->initializeLazyObject()->scard(...\func_get_args()); } public function script($command, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->script(...\func_get_args()); + return $this->initializeLazyObject()->script(...\func_get_args()); } public function strlen($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->strlen(...\func_get_args()); + return $this->initializeLazyObject()->strlen(...\func_get_args()); } public function hlen($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hlen(...\func_get_args()); + return $this->initializeLazyObject()->hlen(...\func_get_args()); } public function llen($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->llen(...\func_get_args()); + return $this->initializeLazyObject()->llen(...\func_get_args()); } public function xack($key, $group, $ids): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xack(...\func_get_args()); + return $this->initializeLazyObject()->xack(...\func_get_args()); } public function xadd($key, $id, $values, $maxlen = 0, $approx = false, $nomkstream = false): \Relay\Relay|false|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xadd(...\func_get_args()); + return $this->initializeLazyObject()->xadd(...\func_get_args()); } public function xclaim($key, $group, $consumer, $min_idle, $ids, $options): \Relay\Relay|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xclaim(...\func_get_args()); + return $this->initializeLazyObject()->xclaim(...\func_get_args()); } public function xautoclaim($key, $group, $consumer, $min_idle, $start, $count = -1, $justid = false): \Relay\Relay|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xautoclaim(...\func_get_args()); + return $this->initializeLazyObject()->xautoclaim(...\func_get_args()); } public function xlen($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xlen(...\func_get_args()); + return $this->initializeLazyObject()->xlen(...\func_get_args()); } public function xgroup($operation, $key = null, $group = null, $id_or_consumer = null, $mkstream = false, $entries_read = -2): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xgroup(...\func_get_args()); + return $this->initializeLazyObject()->xgroup(...\func_get_args()); } public function xdel($key, $ids): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xdel(...\func_get_args()); + return $this->initializeLazyObject()->xdel(...\func_get_args()); } public function xinfo($operation, $arg1 = null, $arg2 = null, $count = -1): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xinfo(...\func_get_args()); + return $this->initializeLazyObject()->xinfo(...\func_get_args()); } public function xpending($key, $group, $start = null, $end = null, $count = -1, $consumer = null, $idle = 0): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xpending(...\func_get_args()); + return $this->initializeLazyObject()->xpending(...\func_get_args()); } public function xrange($key, $start, $end, $count = -1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrange(...\func_get_args()); + return $this->initializeLazyObject()->xrange(...\func_get_args()); } public function xrevrange($key, $end, $start, $count = -1): \Relay\Relay|array|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xrevrange(...\func_get_args()); + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } public function xread($streams, $count = -1, $block = -1): \Relay\Relay|array|bool|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xread(...\func_get_args()); + return $this->initializeLazyObject()->xread(...\func_get_args()); } public function xreadgroup($group, $consumer, $streams, $count = 1, $block = 1): \Relay\Relay|array|bool|null { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xreadgroup(...\func_get_args()); + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } public function xtrim($key, $threshold, $approx = false, $minid = false, $limit = -1): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->xtrim(...\func_get_args()); + return $this->initializeLazyObject()->xtrim(...\func_get_args()); } public function zadd($key, ...$args): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zadd(...\func_get_args()); + return $this->initializeLazyObject()->zadd(...\func_get_args()); } public function zrandmember($key, $options = null): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrandmember(...\func_get_args()); + return $this->initializeLazyObject()->zrandmember(...\func_get_args()); } public function zrange($key, $start, $end, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrange(...\func_get_args()); + return $this->initializeLazyObject()->zrange(...\func_get_args()); } public function zrevrange($key, $start, $end, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrange(...\func_get_args()); + return $this->initializeLazyObject()->zrevrange(...\func_get_args()); } public function zrangebyscore($key, $start, $end, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrangebyscore(...\func_get_args()); } public function zrevrangebyscore($key, $start, $end, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebyscore(...\func_get_args()); } public function zrangestore($dst, $src, $start, $end, $options = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangestore(...\func_get_args()); + return $this->initializeLazyObject()->zrangestore(...\func_get_args()); } public function zrangebylex($key, $min, $max, $offset = -1, $count = -1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrangebylex(...\func_get_args()); } public function zrevrangebylex($key, $max, $min, $offset = -1, $count = -1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zrevrangebylex(...\func_get_args()); } public function zrank($key, $rank, $withscore = false): \Relay\Relay|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrank(...\func_get_args()); + return $this->initializeLazyObject()->zrank(...\func_get_args()); } public function zrevrank($key, $rank, $withscore = false): \Relay\Relay|array|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrevrank(...\func_get_args()); + return $this->initializeLazyObject()->zrevrank(...\func_get_args()); } public function zrem($key, ...$args): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zrem(...\func_get_args()); + return $this->initializeLazyObject()->zrem(...\func_get_args()); } public function zremrangebylex($key, $min, $max): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebylex(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebylex(...\func_get_args()); } public function zremrangebyrank($key, $start, $end): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyrank(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyrank(...\func_get_args()); } public function zremrangebyscore($key, $min, $max): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zremrangebyscore(...\func_get_args()); + return $this->initializeLazyObject()->zremrangebyscore(...\func_get_args()); } public function zcard($key): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcard(...\func_get_args()); + return $this->initializeLazyObject()->zcard(...\func_get_args()); } public function zcount($key, $min, $max): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zcount(...\func_get_args()); + return $this->initializeLazyObject()->zcount(...\func_get_args()); } public function zdiff($keys, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiff(...\func_get_args()); + return $this->initializeLazyObject()->zdiff(...\func_get_args()); } public function zdiffstore($dst, $keys): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zdiffstore(...\func_get_args()); + return $this->initializeLazyObject()->zdiffstore(...\func_get_args()); } public function zincrby($key, $score, $mem): \Relay\Relay|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zincrby(...\func_get_args()); + return $this->initializeLazyObject()->zincrby(...\func_get_args()); } public function zlexcount($key, $min, $max): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zlexcount(...\func_get_args()); + return $this->initializeLazyObject()->zlexcount(...\func_get_args()); } public function zmscore($key, ...$mems): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zmscore(...\func_get_args()); + return $this->initializeLazyObject()->zmscore(...\func_get_args()); } public function zscore($key, $member): \Relay\Relay|false|float { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zscore(...\func_get_args()); + return $this->initializeLazyObject()->zscore(...\func_get_args()); } public function zinter($keys, $weights = null, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinter(...\func_get_args()); + return $this->initializeLazyObject()->zinter(...\func_get_args()); } public function zintercard($keys, $limit = -1): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zintercard(...\func_get_args()); + return $this->initializeLazyObject()->zintercard(...\func_get_args()); } public function zinterstore($dst, $keys, $weights = null, $options = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zinterstore(...\func_get_args()); + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } public function zunion($keys, $weights = null, $options = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunion(...\func_get_args()); + return $this->initializeLazyObject()->zunion(...\func_get_args()); } public function zunionstore($dst, $keys, $weights = null, $options = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zunionstore(...\func_get_args()); + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } public function zpopmin($key, $count = 1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmin(...\func_get_args()); + return $this->initializeLazyObject()->zpopmin(...\func_get_args()); } public function zpopmax($key, $count = 1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->zpopmax(...\func_get_args()); + return $this->initializeLazyObject()->zpopmax(...\func_get_args()); } public function _getKeys() { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->_getKeys(...\func_get_args()); + return $this->initializeLazyObject()->_getKeys(...\func_get_args()); } } From b4f7f57ad4690cc5a77c2eac2d1be2fea8b184cf Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 16 Jun 2024 18:07:30 +0200 Subject: [PATCH 02/44] mark RedisProxyTrait as internal --- Traits/RedisProxyTrait.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Traits/RedisProxyTrait.php b/Traits/RedisProxyTrait.php index c138969b..1acbdf19 100644 --- a/Traits/RedisProxyTrait.php +++ b/Traits/RedisProxyTrait.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Cache\Traits; +/** + * @internal + */ trait RedisProxyTrait { private \Closure $initializer; From 360e65cff267446280ea2626f61403471dcc040d Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 20 Jun 2024 17:52:34 +0200 Subject: [PATCH 03/44] Prefix all sprintf() calls --- Adapter/AbstractAdapter.php | 6 +++--- Adapter/AbstractTagAwareAdapter.php | 6 +++--- Adapter/ApcuAdapter.php | 2 +- Adapter/ArrayAdapter.php | 6 +++--- Adapter/ChainAdapter.php | 4 ++-- Adapter/DoctrineDbalAdapter.php | 4 ++-- Adapter/MemcachedAdapter.php | 2 +- Adapter/ParameterNormalizer.php | 2 +- Adapter/PdoAdapter.php | 10 +++++----- Adapter/PhpArrayAdapter.php | 22 ++++++++++----------- Adapter/PhpFilesAdapter.php | 6 +++--- Adapter/ProxyAdapter.php | 2 +- Adapter/RedisTagAwareAdapter.php | 6 +++--- Adapter/TraceableAdapter.php | 2 +- CacheItem.php | 12 +++++------ DependencyInjection/CachePoolPass.php | 4 ++-- DependencyInjection/CachePoolPrunerPass.php | 2 +- LockRegistry.php | 2 +- Psr16Cache.php | 6 +++--- Tests/Adapter/DoctrineDbalAdapterTest.php | 2 +- Tests/Adapter/PdoAdapterTest.php | 2 +- Tests/Psr16CacheTest.php | 4 ++-- Tests/Traits/RedisTraitTest.php | 12 +++++------ Traits/AbstractAdapterTrait.php | 2 +- Traits/ContractsTrait.php | 2 +- Traits/FilesystemCommonTrait.php | 4 ++-- Traits/FilesystemTrait.php | 2 +- Traits/RedisTrait.php | 12 +++++------ 28 files changed, 74 insertions(+), 74 deletions(-) diff --git a/Adapter/AbstractAdapter.php b/Adapter/AbstractAdapter.php index 5d6336ee..c03868da 100644 --- a/Adapter/AbstractAdapter.php +++ b/Adapter/AbstractAdapter.php @@ -40,7 +40,7 @@ protected function __construct(string $namespace = '', int $defaultLifetime = 0) $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; $this->defaultLifetime = $defaultLifetime; if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { - throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } self::$createCacheItem ??= \Closure::bind( static function ($key, $value, $isHit) { @@ -158,7 +158,7 @@ public function commit(): bool $ok = false; $v = $values[$id]; $type = get_debug_type($v); - $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } else { @@ -181,7 +181,7 @@ public function commit(): bool } $ok = false; $type = get_debug_type($v); - $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } diff --git a/Adapter/AbstractTagAwareAdapter.php b/Adapter/AbstractTagAwareAdapter.php index ef62b4fb..a1af6141 100644 --- a/Adapter/AbstractTagAwareAdapter.php +++ b/Adapter/AbstractTagAwareAdapter.php @@ -42,7 +42,7 @@ protected function __construct(string $namespace = '', int $defaultLifetime = 0) $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; $this->defaultLifetime = $defaultLifetime; if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { - throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } self::$createCacheItem ??= \Closure::bind( static function ($key, $value, $isHit) { @@ -194,7 +194,7 @@ public function commit(): bool $ok = false; $v = $values[$id]; $type = get_debug_type($v); - $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } else { @@ -218,7 +218,7 @@ public function commit(): bool } $ok = false; $type = get_debug_type($v); - $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } diff --git a/Adapter/ApcuAdapter.php b/Adapter/ApcuAdapter.php index 03b512f0..ddb72100 100644 --- a/Adapter/ApcuAdapter.php +++ b/Adapter/ApcuAdapter.php @@ -79,7 +79,7 @@ protected function doHave(string $id): bool protected function doClear(string $namespace): bool { return isset($namespace[0]) && class_exists(\APCUIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) - ? apcu_delete(new \APCUIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) + ? apcu_delete(new \APCUIterator(\sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) : apcu_clear_cache(); } diff --git a/Adapter/ArrayAdapter.php b/Adapter/ArrayAdapter.php index 0f1c49db..97be852a 100644 --- a/Adapter/ArrayAdapter.php +++ b/Adapter/ArrayAdapter.php @@ -46,11 +46,11 @@ public function __construct( private int $maxItems = 0, ) { if (0 > $maxLifetime) { - throw new InvalidArgumentException(sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime)); + throw new InvalidArgumentException(\sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime)); } if (0 > $maxItems) { - throw new InvalidArgumentException(sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems)); + throw new InvalidArgumentException(\sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems)); } self::$createCacheItem ??= \Closure::bind( @@ -307,7 +307,7 @@ private function freeze($value, string $key): string|int|float|bool|array|\UnitE } catch (\Exception $e) { unset($this->values[$key], $this->tags[$key]); $type = get_debug_type($value); - $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage()); + $message = \sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage()); CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]); return null; diff --git a/Adapter/ChainAdapter.php b/Adapter/ChainAdapter.php index 1418cff0..09fcfdcc 100644 --- a/Adapter/ChainAdapter.php +++ b/Adapter/ChainAdapter.php @@ -52,7 +52,7 @@ public function __construct( foreach ($adapters as $adapter) { if (!$adapter instanceof CacheItemPoolInterface) { - throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class)); + throw new InvalidArgumentException(\sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class)); } if ('cli' === \PHP_SAPI && $adapter instanceof ApcuAdapter && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) { continue; // skip putting APCu in the chain when the backend is disabled @@ -76,7 +76,7 @@ static function ($sourceItem, $item, $defaultLifetime, $sourceMetadata = null) { $item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata; if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) { - $item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY]))); + $item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY]))); } elseif (0 < $defaultLifetime) { $item->expiresAfter($defaultLifetime); } diff --git a/Adapter/DoctrineDbalAdapter.php b/Adapter/DoctrineDbalAdapter.php index ae2bea7e..c69c777c 100644 --- a/Adapter/DoctrineDbalAdapter.php +++ b/Adapter/DoctrineDbalAdapter.php @@ -63,7 +63,7 @@ public function __construct( ?MarshallerInterface $marshaller = null, ) { if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) { - throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); + throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); } if ($connOrDsn instanceof Connection) { @@ -140,7 +140,7 @@ public function prune(): bool if ('' !== $this->namespace) { $deleteSql .= " AND $this->idCol LIKE ?"; - $params[] = sprintf('%s%%', $this->namespace); + $params[] = \sprintf('%s%%', $this->namespace); $paramTypes[] = ParameterType::STRING; } diff --git a/Adapter/MemcachedAdapter.php b/Adapter/MemcachedAdapter.php index 033d9871..d882ef1b 100644 --- a/Adapter/MemcachedAdapter.php +++ b/Adapter/MemcachedAdapter.php @@ -311,7 +311,7 @@ private function getClient(): \Memcached throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); } if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) { - throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix)); + throw new CacheException(\sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix)); } return $this->client = $this->lazyClient; diff --git a/Adapter/ParameterNormalizer.php b/Adapter/ParameterNormalizer.php index a6896402..483df1c0 100644 --- a/Adapter/ParameterNormalizer.php +++ b/Adapter/ParameterNormalizer.php @@ -29,7 +29,7 @@ public static function normalizeDuration(string $duration): int try { return \DateTimeImmutable::createFromFormat('U', 0)->add(new \DateInterval($duration))->getTimestamp(); } catch (\Exception $e) { - throw new \InvalidArgumentException(sprintf('Cannot parse date interval "%s".', $duration), 0, $e); + throw new \InvalidArgumentException(\sprintf('Cannot parse date interval "%s".', $duration), 0, $e); } } } diff --git a/Adapter/PdoAdapter.php b/Adapter/PdoAdapter.php index b18428d6..525e2c6d 100644 --- a/Adapter/PdoAdapter.php +++ b/Adapter/PdoAdapter.php @@ -57,16 +57,16 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface public function __construct(#[\SensitiveParameter] \PDO|string $connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null) { if (\is_string($connOrDsn) && str_contains($connOrDsn, '://')) { - throw new InvalidArgumentException(sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class)); + throw new InvalidArgumentException(\sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class)); } if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) { - throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); + throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); } if ($connOrDsn instanceof \PDO) { if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { - throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__)); + throw new InvalidArgumentException(\sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__)); } $this->conn = $connOrDsn; @@ -123,7 +123,7 @@ public function createTable(): void 'pgsql' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", 'oci' => "CREATE TABLE $this->table ($this->idCol VARCHAR2(255) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", 'sqlsrv' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", - default => throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $driver)), + default => throw new \DomainException(\sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $driver)), }; $this->getConnection()->exec($sql); @@ -147,7 +147,7 @@ public function prune(): bool $delete->bindValue(':time', time(), \PDO::PARAM_INT); if ('' !== $this->namespace) { - $delete->bindValue(':namespace', sprintf('%s%%', $this->namespace), \PDO::PARAM_STR); + $delete->bindValue(':namespace', \sprintf('%s%%', $this->namespace), \PDO::PARAM_STR); } try { return $delete->execute(); diff --git a/Adapter/PhpArrayAdapter.php b/Adapter/PhpArrayAdapter.php index f92a2380..8b574b64 100644 --- a/Adapter/PhpArrayAdapter.php +++ b/Adapter/PhpArrayAdapter.php @@ -111,7 +111,7 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array public function getItem(mixed $key): CacheItem { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } if (!isset($this->values)) { $this->initialize(); @@ -141,7 +141,7 @@ public function getItems(array $keys = []): iterable { foreach ($keys as $key) { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } } if (!isset($this->values)) { @@ -154,7 +154,7 @@ public function getItems(array $keys = []): iterable public function hasItem(mixed $key): bool { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } if (!isset($this->values)) { $this->initialize(); @@ -166,7 +166,7 @@ public function hasItem(mixed $key): bool public function deleteItem(mixed $key): bool { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } if (!isset($this->values)) { $this->initialize(); @@ -182,7 +182,7 @@ public function deleteItems(array $keys): bool foreach ($keys as $key) { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } if (isset($this->keys[$key])) { @@ -250,21 +250,21 @@ public function warmUp(array $values): array { if (file_exists($this->file)) { if (!is_file($this->file)) { - throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file)); + throw new InvalidArgumentException(\sprintf('Cache path exists and is not a file: "%s".', $this->file)); } if (!is_writable($this->file)) { - throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file)); + throw new InvalidArgumentException(\sprintf('Cache file is not writable: "%s".', $this->file)); } } else { $directory = \dirname($this->file); if (!is_dir($directory) && !@mkdir($directory, 0777, true)) { - throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); + throw new InvalidArgumentException(\sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); } if (!is_writable($directory)) { - throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory)); + throw new InvalidArgumentException(\sprintf('Cache directory is not writable: "%s".', $directory)); } } @@ -291,7 +291,7 @@ public function warmUp(array $values): array try { $value = VarExporter::export($value, $isStaticValue, $preload); } catch (\Exception $e) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); + throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); } } elseif (\is_string($value)) { // Wrap "N;" in a closure to not confuse it with an encoded `null` @@ -300,7 +300,7 @@ public function warmUp(array $values): array } $value = var_export($value, true); } elseif (!\is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); + throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); } else { $value = var_export($value, true); } diff --git a/Adapter/PhpFilesAdapter.php b/Adapter/PhpFilesAdapter.php index 917ff161..3405084a 100644 --- a/Adapter/PhpFilesAdapter.php +++ b/Adapter/PhpFilesAdapter.php @@ -216,7 +216,7 @@ protected function doSave(array $values, int $lifetime): array|bool try { $value = VarExporter::export($value, $isStaticValue); } catch (\Exception $e) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); + throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); } } elseif (\is_string($value)) { // Wrap "N;" in a closure to not confuse it with an encoded `null` @@ -225,7 +225,7 @@ protected function doSave(array $values, int $lifetime): array|bool } $value = var_export($value, true); } elseif (!\is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); + throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); } else { $value = var_export($value, true); } @@ -254,7 +254,7 @@ protected function doSave(array $values, int $lifetime): array|bool } if (!$ok && !is_writable($this->directory)) { - throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); + throw new CacheException(\sprintf('Cache directory is not writable (%s).', $this->directory)); } return $ok; diff --git a/Adapter/ProxyAdapter.php b/Adapter/ProxyAdapter.php index c022dd5f..56212260 100644 --- a/Adapter/ProxyAdapter.php +++ b/Adapter/ProxyAdapter.php @@ -73,7 +73,7 @@ static function ($key, $innerItem, $poolHash) { self::$setInnerItem ??= \Closure::bind( static function (CacheItemInterface $innerItem, CacheItem $item, $expiry = null) { $innerItem->set($item->pack()); - $innerItem->expiresAt(($expiry ?? $item->expiry) ? \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $expiry ?? $item->expiry)) : null); + $innerItem->expiresAt(($expiry ?? $item->expiry) ? \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $expiry ?? $item->expiry)) : null); }, null, CacheItem::class diff --git a/Adapter/RedisTagAwareAdapter.php b/Adapter/RedisTagAwareAdapter.php index f71622b6..7b282375 100644 --- a/Adapter/RedisTagAwareAdapter.php +++ b/Adapter/RedisTagAwareAdapter.php @@ -66,7 +66,7 @@ public function __construct( ?MarshallerInterface $marshaller = null, ) { if ($redis instanceof \Predis\ClientInterface && $redis->getConnection() instanceof ClusterInterface && !$redis->getConnection() instanceof PredisCluster) { - throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection()))); + throw new InvalidArgumentException(\sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection()))); } $isRelay = $redis instanceof Relay; @@ -75,7 +75,7 @@ public function __construct( foreach (\is_array($compression) ? $compression : [$compression] as $c) { if ($isRelay ? Relay::COMPRESSION_NONE : \Redis::COMPRESSION_NONE !== $c) { - throw new InvalidArgumentException(sprintf('redis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class)); + throw new InvalidArgumentException(\sprintf('redis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class)); } } } @@ -87,7 +87,7 @@ protected function doSave(array $values, int $lifetime, array $addTagData = [], { $eviction = $this->getRedisEvictionPolicy(); if ('noeviction' !== $eviction && !str_starts_with($eviction, 'volatile-')) { - throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); + throw new LogicException(\sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); } // serialize values diff --git a/Adapter/TraceableAdapter.php b/Adapter/TraceableAdapter.php index b5bce143..fdad2cf2 100644 --- a/Adapter/TraceableAdapter.php +++ b/Adapter/TraceableAdapter.php @@ -38,7 +38,7 @@ public function __construct(AdapterInterface $pool) public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { if (!$this->pool instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); } $isHit = true; diff --git a/CacheItem.php b/CacheItem.php index 1a81706d..ec2c0c5c 100644 --- a/CacheItem.php +++ b/CacheItem.php @@ -81,7 +81,7 @@ public function expiresAfter(mixed $time): static } elseif (\is_int($time)) { $this->expiry = $time + microtime(true); } else { - throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time))); + throw new InvalidArgumentException(\sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time))); } return $this; @@ -90,14 +90,14 @@ public function expiresAfter(mixed $time): static public function tag(mixed $tags): static { if (!$this->isTaggable) { - throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key)); + throw new LogicException(\sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key)); } if (!\is_array($tags) && !$tags instanceof \Traversable) { // don't use is_iterable(), it's slow $tags = [$tags]; } foreach ($tags as $tag) { if (!\is_string($tag) && !$tag instanceof \Stringable) { - throw new InvalidArgumentException(sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', get_debug_type($tag))); + throw new InvalidArgumentException(\sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', get_debug_type($tag))); } $tag = (string) $tag; if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) { @@ -107,7 +107,7 @@ public function tag(mixed $tags): static throw new InvalidArgumentException('Cache tag length must be greater than zero.'); } if (false !== strpbrk($tag, self::RESERVED_CHARACTERS)) { - throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS)); + throw new InvalidArgumentException(\sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS)); } $this->newMetadata[self::METADATA_TAGS][$tag] = $tag; } @@ -130,13 +130,13 @@ public function getMetadata(): array public static function validateKey($key): string { if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); + throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); } if ('' === $key) { throw new InvalidArgumentException('Cache key length must be greater than zero.'); } if (false !== strpbrk($key, self::RESERVED_CHARACTERS)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS)); + throw new InvalidArgumentException(\sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS)); } return $key; diff --git a/DependencyInjection/CachePoolPass.php b/DependencyInjection/CachePoolPass.php index 081d82cd..e62febbc 100644 --- a/DependencyInjection/CachePoolPass.php +++ b/DependencyInjection/CachePoolPass.php @@ -106,7 +106,7 @@ public function process(ContainerBuilder $container): void } if (ChainAdapter::class === $chainedClass) { - throw new InvalidArgumentException(sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent())); + throw new InvalidArgumentException(\sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent())); } $i = 0; @@ -164,7 +164,7 @@ public function process(ContainerBuilder $container): void unset($tags[0][$attr]); } if (!empty($tags[0])) { - throw new InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime", "early_expiration_message_bus" and "reset", found "%s".', $id, implode('", "', array_keys($tags[0])))); + throw new InvalidArgumentException(\sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime", "early_expiration_message_bus" and "reset", found "%s".', $id, implode('", "', array_keys($tags[0])))); } if (null !== $clearer) { diff --git a/DependencyInjection/CachePoolPrunerPass.php b/DependencyInjection/CachePoolPrunerPass.php index 69b69fb4..68386f57 100644 --- a/DependencyInjection/CachePoolPrunerPass.php +++ b/DependencyInjection/CachePoolPrunerPass.php @@ -35,7 +35,7 @@ public function process(ContainerBuilder $container): void $class = $container->getParameterBag()->resolveValue($container->getDefinition($id)->getClass()); if (!$reflection = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } if ($reflection->implementsInterface(PruneableInterface::class)) { diff --git a/LockRegistry.php b/LockRegistry.php index c5c5fde8..6923b40b 100644 --- a/LockRegistry.php +++ b/LockRegistry.php @@ -105,7 +105,7 @@ public static function compute(callable $callback, ItemInterface $item, bool &$s $locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock); if ($locked || !$wouldBlock) { - $logger?->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]); + $logger?->info(\sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]); self::$lockedFiles[$key] = true; $value = $callback($item, $save); diff --git a/Psr16Cache.php b/Psr16Cache.php index f21384fe..01494d71 100644 --- a/Psr16Cache.php +++ b/Psr16Cache.php @@ -135,7 +135,7 @@ public function getMultiple($keys, $default = null): iterable if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); } elseif (!\is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys))); + throw new InvalidArgumentException(\sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys))); } try { @@ -166,7 +166,7 @@ public function setMultiple($values, $ttl = null): bool { $valuesIsArray = \is_array($values); if (!$valuesIsArray && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values))); + throw new InvalidArgumentException(\sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values))); } $items = []; @@ -215,7 +215,7 @@ public function deleteMultiple($keys): bool if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); } elseif (!\is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys))); + throw new InvalidArgumentException(\sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys))); } try { diff --git a/Tests/Adapter/DoctrineDbalAdapterTest.php b/Tests/Adapter/DoctrineDbalAdapterTest.php index 9b7c4487..108d3be2 100644 --- a/Tests/Adapter/DoctrineDbalAdapterTest.php +++ b/Tests/Adapter/DoctrineDbalAdapterTest.php @@ -160,7 +160,7 @@ protected function isPruned(DoctrineDbalAdapter $cache, string $name): bool /** @var Connection $conn */ $conn = $connProp->getValue($cache); - $result = $conn->executeQuery('SELECT 1 FROM cache_items WHERE item_id LIKE ?', [sprintf('%%%s', $name)]); + $result = $conn->executeQuery('SELECT 1 FROM cache_items WHERE item_id LIKE ?', [\sprintf('%%%s', $name)]); return 1 !== (int) $result->fetchOne(); } diff --git a/Tests/Adapter/PdoAdapterTest.php b/Tests/Adapter/PdoAdapterTest.php index f55a4ce2..49f3da83 100644 --- a/Tests/Adapter/PdoAdapterTest.php +++ b/Tests/Adapter/PdoAdapterTest.php @@ -134,7 +134,7 @@ protected function isPruned(PdoAdapter $cache, string $name): bool /** @var \PDOStatement $select */ $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); - $select->bindValue(':id', sprintf('%%%s', $name)); + $select->bindValue(':id', \sprintf('%%%s', $name)); $select->execute(); return 1 !== (int) $select->fetch(\PDO::FETCH_COLUMN); diff --git a/Tests/Psr16CacheTest.php b/Tests/Psr16CacheTest.php index e4ed4674..322796c3 100644 --- a/Tests/Psr16CacheTest.php +++ b/Tests/Psr16CacheTest.php @@ -32,7 +32,7 @@ protected function setUp(): void $pool = $this->createSimpleCache(); if ($pool instanceof Psr16Cache) { - $pool = ((array) $pool)[sprintf("\0%s\0pool", Psr16Cache::class)]; + $pool = ((array) $pool)[\sprintf("\0%s\0pool", Psr16Cache::class)]; } if (!$pool instanceof PruneableInterface) { @@ -167,7 +167,7 @@ protected function isPruned(CacheInterface $cache, string $name): bool $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); } - $pool = ((array) $cache)[sprintf("\0%s\0pool", Psr16Cache::class)]; + $pool = ((array) $cache)[\sprintf("\0%s\0pool", Psr16Cache::class)]; $getFileMethod = (new \ReflectionObject($pool))->getMethod('getFile'); return !file_exists($getFileMethod->invoke($pool, $name)); diff --git a/Tests/Traits/RedisTraitTest.php b/Tests/Traits/RedisTraitTest.php index 04665608..9bb4a65f 100644 --- a/Tests/Traits/RedisTraitTest.php +++ b/Tests/Traits/RedisTraitTest.php @@ -25,7 +25,7 @@ class RedisTraitTest extends TestCase public function testCreateConnection(string $dsn, string $expectedClass) { if (!class_exists($expectedClass)) { - self::markTestSkipped(sprintf('The "%s" class is required.', $expectedClass)); + self::markTestSkipped(\sprintf('The "%s" class is required.', $expectedClass)); } if (!getenv('REDIS_CLUSTER_HOSTS')) { self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); @@ -56,23 +56,23 @@ public function testUrlDecodeParameters() public static function provideCreateConnection(): array { - $hosts = array_map(fn ($host) => sprintf('host[%s]', $host), explode(' ', getenv('REDIS_CLUSTER_HOSTS'))); + $hosts = array_map(fn ($host) => \sprintf('host[%s]', $host), explode(' ', getenv('REDIS_CLUSTER_HOSTS'))); return [ [ - sprintf('redis:?%s&redis_cluster=1', $hosts[0]), + \sprintf('redis:?%s&redis_cluster=1', $hosts[0]), 'RedisCluster', ], [ - sprintf('redis:?%s&redis_cluster=true', $hosts[0]), + \sprintf('redis:?%s&redis_cluster=true', $hosts[0]), 'RedisCluster', ], [ - sprintf('redis:?%s', $hosts[0]), + \sprintf('redis:?%s', $hosts[0]), 'Redis', ], [ - 'dsn' => sprintf('redis:?%s', implode('&', \array_slice($hosts, 0, 2))), + 'dsn' => \sprintf('redis:?%s', implode('&', \array_slice($hosts, 0, 2))), 'RedisArray', ], ]; diff --git a/Traits/AbstractAdapterTrait.php b/Traits/AbstractAdapterTrait.php index 222bc545..6a716743 100644 --- a/Traits/AbstractAdapterTrait.php +++ b/Traits/AbstractAdapterTrait.php @@ -300,7 +300,7 @@ private function generateItems(iterable $items, array &$keys): \Generator try { foreach ($items as $id => $value) { if (!isset($keys[$id])) { - throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys))); + throw new InvalidArgumentException(\sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys))); } $key = $keys[$id]; unset($keys[$id]); diff --git a/Traits/ContractsTrait.php b/Traits/ContractsTrait.php index 8d830f0a..d461582d 100644 --- a/Traits/ContractsTrait.php +++ b/Traits/ContractsTrait.php @@ -62,7 +62,7 @@ public function setCallbackWrapper(?callable $callbackWrapper): callable private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null): mixed { if (0 > $beta ??= 1.0) { - throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)); + throw new InvalidArgumentException(\sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)); } static $setMetadata; diff --git a/Traits/FilesystemCommonTrait.php b/Traits/FilesystemCommonTrait.php index 7fa0f2e8..32f51bc3 100644 --- a/Traits/FilesystemCommonTrait.php +++ b/Traits/FilesystemCommonTrait.php @@ -32,7 +32,7 @@ private function init(string $namespace, ?string $directory): void } if (isset($namespace[0])) { if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { - throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); + throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); } $directory .= \DIRECTORY_SEPARATOR.$namespace; } else { @@ -44,7 +44,7 @@ private function init(string $namespace, ?string $directory): void $directory .= \DIRECTORY_SEPARATOR; // On Windows the whole path is limited to 258 chars if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) { - throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory)); + throw new InvalidArgumentException(\sprintf('Cache directory too long (%s).', $directory)); } $this->directory = $directory; diff --git a/Traits/FilesystemTrait.php b/Traits/FilesystemTrait.php index 47e9b838..05fa10e9 100644 --- a/Traits/FilesystemTrait.php +++ b/Traits/FilesystemTrait.php @@ -92,7 +92,7 @@ protected function doSave(array $values, int $lifetime): array|bool } if ($failed && !is_writable($this->directory)) { - throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); + throw new CacheException(\sprintf('Cache directory is not writable (%s).', $this->directory)); } return $failed; diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 8183f929..c5bfa13f 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -57,7 +57,7 @@ private function init(\Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInter parent::__construct($namespace, $defaultLifetime); 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 ($redis instanceof \Predis\ClientInterface && $redis->getOptions()->exceptions) { @@ -202,7 +202,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra }; if (isset($params['redis_sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { - throw new CacheException(sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class)); + throw new CacheException(\sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class)); } $isRedisExt = is_a($class, \Redis::class, true); @@ -259,7 +259,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } while (++$hostIndex < \count($hosts) && !$address); if (isset($params['redis_sentinel']) && !$address) { - throw new InvalidArgumentException(sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']), previous: $redisException ?? null); + throw new InvalidArgumentException(\sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']), previous: $redisException ?? null); } try { @@ -294,7 +294,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra restore_error_handler(); } if (!$isConnected) { - $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? sprintf(' (%s)', $error[1]) : ''; + $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? \sprintf(' (%s)', $error[1]) : ''; throw new InvalidArgumentException('Redis connection failed: '.$error.'.'); } @@ -419,9 +419,9 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $redis->getConnection()->setSentinelTimeout($params['timeout']); } } elseif (class_exists($class, false)) { - throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster", "Relay\Relay" nor "Predis\ClientInterface".', $class)); + throw new InvalidArgumentException(\sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster", "Relay\Relay" nor "Predis\ClientInterface".', $class)); } else { - throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + throw new InvalidArgumentException(\sprintf('Class "%s" does not exist.', $class)); } return $redis; From 9b2a2d5c9319d98a506f0df49dd828e0e090b0ad Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Sun, 16 Jun 2024 17:17:26 +0200 Subject: [PATCH 04/44] chore: CS fixes --- Tests/Traits/RedisTraitTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Traits/RedisTraitTest.php b/Tests/Traits/RedisTraitTest.php index 9bb4a65f..cbf15eb8 100644 --- a/Tests/Traits/RedisTraitTest.php +++ b/Tests/Traits/RedisTraitTest.php @@ -31,7 +31,7 @@ public function testCreateConnection(string $dsn, string $expectedClass) self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); } - $mock = new class () { + $mock = new class() { use RedisTrait; }; $connection = $mock::createConnection($dsn); @@ -45,7 +45,7 @@ public function testUrlDecodeParameters() self::markTestSkipped('REDIS_AUTHENTICATED_HOST env var is not defined.'); } - $mock = new class () { + $mock = new class() { use RedisTrait; }; $connection = $mock::createConnection('redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST')); @@ -104,7 +104,7 @@ public function testPconnectSelectsCorrectDatabase() } try { - $mock = new class () { + $mock = new class() { use RedisTrait; }; From 7e9b2a142a045cbb8aa3d8cff4bac320b18facba Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 6 Jul 2024 09:57:16 +0200 Subject: [PATCH 05/44] Update .gitattributes --- .gitattributes | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 84c7add0..14c3c359 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ /Tests export-ignore /phpunit.xml.dist export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore +/.git* export-ignore From c091304e62ad137bd6a43ea06046491460d2f2ca Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 17 Jul 2024 09:53:22 +0200 Subject: [PATCH 06/44] do not use LazyProxyTrait in RelayProxyTrait --- Tests/Traits/RedisProxiesTest.php | 4 +-- Traits/RelayProxyTrait.php | 50 +++++++++++++++---------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index bddd6839..293770d7 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -72,10 +72,10 @@ public function testRelayProxy() continue; } - $return = $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; + $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; $expectedMethods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args}); + {$return}\$this->initializeLazyObject()->{$method->name}({$args}); } EOPHP; diff --git a/Traits/RelayProxyTrait.php b/Traits/RelayProxyTrait.php index a1d252b9..25837071 100644 --- a/Traits/RelayProxyTrait.php +++ b/Traits/RelayProxyTrait.php @@ -24,122 +24,122 @@ public function copy($src, $dst, $options = null): \Relay\Relay|bool public function jsonArrAppend($key, $value_or_array, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrAppend(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrAppend(...\func_get_args()); } public function jsonArrIndex($key, $path, $value, $start = 0, $stop = -1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrIndex(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrIndex(...\func_get_args()); } public function jsonArrInsert($key, $path, $index, $value, ...$other_values): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrInsert(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrInsert(...\func_get_args()); } public function jsonArrLen($key, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrLen(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrLen(...\func_get_args()); } public function jsonArrPop($key, $path = null, $index = -1): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrPop(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrPop(...\func_get_args()); } public function jsonArrTrim($key, $path, $start, $stop): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonArrTrim(...\func_get_args()); + return $this->initializeLazyObject()->jsonArrTrim(...\func_get_args()); } public function jsonClear($key, $path = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonClear(...\func_get_args()); + return $this->initializeLazyObject()->jsonClear(...\func_get_args()); } public function jsonDebug($command, $key, $path = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonDebug(...\func_get_args()); + return $this->initializeLazyObject()->jsonDebug(...\func_get_args()); } public function jsonDel($key, $path = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonDel(...\func_get_args()); + return $this->initializeLazyObject()->jsonDel(...\func_get_args()); } public function jsonForget($key, $path = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonForget(...\func_get_args()); + return $this->initializeLazyObject()->jsonForget(...\func_get_args()); } public function jsonGet($key, $options = [], ...$paths): mixed { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonGet(...\func_get_args()); + return $this->initializeLazyObject()->jsonGet(...\func_get_args()); } public function jsonMerge($key, $path, $value): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMerge(...\func_get_args()); + return $this->initializeLazyObject()->jsonMerge(...\func_get_args()); } public function jsonMget($key_or_array, $path): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMget(...\func_get_args()); + return $this->initializeLazyObject()->jsonMget(...\func_get_args()); } public function jsonMset($key, $path, $value, ...$other_triples): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonMset(...\func_get_args()); + return $this->initializeLazyObject()->jsonMset(...\func_get_args()); } public function jsonNumIncrBy($key, $path, $value): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonNumIncrBy(...\func_get_args()); + return $this->initializeLazyObject()->jsonNumIncrBy(...\func_get_args()); } public function jsonNumMultBy($key, $path, $value): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonNumMultBy(...\func_get_args()); + return $this->initializeLazyObject()->jsonNumMultBy(...\func_get_args()); } public function jsonObjKeys($key, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonObjKeys(...\func_get_args()); + return $this->initializeLazyObject()->jsonObjKeys(...\func_get_args()); } public function jsonObjLen($key, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonObjLen(...\func_get_args()); + return $this->initializeLazyObject()->jsonObjLen(...\func_get_args()); } public function jsonResp($key, $path = null): \Relay\Relay|array|false|int|string { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonResp(...\func_get_args()); + return $this->initializeLazyObject()->jsonResp(...\func_get_args()); } public function jsonSet($key, $path, $value, $condition = null): \Relay\Relay|bool { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonSet(...\func_get_args()); + return $this->initializeLazyObject()->jsonSet(...\func_get_args()); } public function jsonStrAppend($key, $value, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonStrAppend(...\func_get_args()); + return $this->initializeLazyObject()->jsonStrAppend(...\func_get_args()); } public function jsonStrLen($key, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonStrLen(...\func_get_args()); + return $this->initializeLazyObject()->jsonStrLen(...\func_get_args()); } public function jsonToggle($key, $path): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonToggle(...\func_get_args()); + return $this->initializeLazyObject()->jsonToggle(...\func_get_args()); } public function jsonType($key, $path = null): \Relay\Relay|array|false { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->jsonType(...\func_get_args()); + return $this->initializeLazyObject()->jsonType(...\func_get_args()); } } } else { @@ -150,7 +150,7 @@ trait RelayProxyTrait { public function copy($src, $dst, $options = null): \Relay\Relay|false|int { - return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->copy(...\func_get_args()); + return $this->initializeLazyObject()->copy(...\func_get_args()); } } } From b5b00299bc584b763bfa581c94310515809654bd Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 13 Apr 2024 14:18:00 +0200 Subject: [PATCH 07/44] [PhpUnitBridge] Add ExpectUserDeprecationMessageTrait --- Tests/Adapter/CouchbaseBucketAdapterTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Adapter/CouchbaseBucketAdapterTest.php b/Tests/Adapter/CouchbaseBucketAdapterTest.php index d7511bc6..35c1591c 100644 --- a/Tests/Adapter/CouchbaseBucketAdapterTest.php +++ b/Tests/Adapter/CouchbaseBucketAdapterTest.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Cache\Tests\Adapter; use Psr\Cache\CacheItemPoolInterface; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; +use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait; use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter; @@ -26,7 +26,7 @@ */ class CouchbaseBucketAdapterTest extends AdapterTestCase { - use ExpectDeprecationTrait; + use ExpectUserDeprecationMessageTrait; protected $skippedTests = [ 'testClearPrefix' => 'Couchbase cannot clear by prefix', @@ -36,7 +36,7 @@ class CouchbaseBucketAdapterTest extends AdapterTestCase protected function setUp(): void { - $this->expectDeprecation('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.'); + $this->expectUserDeprecationMessage('Since symfony/cache 7.1: The "Symfony\Component\Cache\Adapter\CouchbaseBucketAdapter" class is deprecated, use "Symfony\Component\Cache\Adapter\CouchbaseCollectionAdapter" instead.'); $this->client = AbstractAdapter::createConnection('couchbase://'.getenv('COUCHBASE_HOST').'/cache', ['username' => getenv('COUCHBASE_USER'), 'password' => getenv('COUCHBASE_PASS')] From fd6121840d8730a906d4b52ce7b47c44cf92d7d6 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 22 Jul 2024 16:54:13 +0200 Subject: [PATCH 08/44] [Cache] Use tempnam() instead of uniquid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to produce a temporary file --- Adapter/PhpArrayAdapter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adapter/PhpArrayAdapter.php b/Adapter/PhpArrayAdapter.php index 8b574b64..81d1ac81 100644 --- a/Adapter/PhpArrayAdapter.php +++ b/Adapter/PhpArrayAdapter.php @@ -41,7 +41,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte private static array $valuesCache = []; /** - * @param string $file The PHP file were values are cached + * @param string $file The PHP file where values are cached * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit */ public function __construct( @@ -321,7 +321,7 @@ public function warmUp(array $values): array $dump .= "\n], [\n\n{$dumpedValues}\n]];\n"; - $tmpFile = uniqid($this->file, true); + $tmpFile = tempnam(dirname($this->file), basename($this->file)); file_put_contents($tmpFile, $dump); @chmod($tmpFile, 0666 & ~umask()); From be87c599a9a1d670eda966ab3303a5cfc0ca2eba Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 22 Jul 2024 10:27:43 +0200 Subject: [PATCH 09/44] Use CPP where possible --- Adapter/PhpFilesAdapter.php | 8 +++----- Adapter/TraceableAdapter.php | 7 +++---- Messenger/EarlyExpirationMessage.php | 14 +++++--------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/Adapter/PhpFilesAdapter.php b/Adapter/PhpFilesAdapter.php index 3405084a..df0d0e71 100644 --- a/Adapter/PhpFilesAdapter.php +++ b/Adapter/PhpFilesAdapter.php @@ -305,10 +305,8 @@ private function getFileKey(string $file): string */ class LazyValue { - public string $file; - - public function __construct(string $file) - { - $this->file = $file; + public function __construct( + public string $file, + ) { } } diff --git a/Adapter/TraceableAdapter.php b/Adapter/TraceableAdapter.php index fdad2cf2..8fe6cf37 100644 --- a/Adapter/TraceableAdapter.php +++ b/Adapter/TraceableAdapter.php @@ -27,12 +27,11 @@ */ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface { - protected AdapterInterface $pool; private array $calls = []; - public function __construct(AdapterInterface $pool) - { - $this->pool = $pool; + public function __construct( + protected AdapterInterface $pool, + ) { } public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed diff --git a/Messenger/EarlyExpirationMessage.php b/Messenger/EarlyExpirationMessage.php index 6056ebab..de8256b9 100644 --- a/Messenger/EarlyExpirationMessage.php +++ b/Messenger/EarlyExpirationMessage.php @@ -20,10 +20,6 @@ */ final class EarlyExpirationMessage { - private CacheItem $item; - private string $pool; - private string|array $callback; - public static function create(ReverseContainer $reverseContainer, callable $callback, CacheItem $item, AdapterInterface $pool): ?self { try { @@ -91,10 +87,10 @@ public function findCallback(ReverseContainer $reverseContainer): callable return $callback; } - private function __construct(CacheItem $item, string $pool, string|array $callback) - { - $this->item = $item; - $this->pool = $pool; - $this->callback = $callback; + private function __construct( + private CacheItem $item, + private string $pool, + private string|array $callback, + ) { } } From 726d5c486d40f667a387e5cce0670b7afc2680ad Mon Sep 17 00:00:00 2001 From: Martijn Croonen Date: Wed, 10 Jul 2024 22:22:53 +0200 Subject: [PATCH 10/44] [Cache] Stop defaulting to igbinary in `DefaultMarshaller` igbinary used to be a drop in replacement for PHP's `serialize` but recent changes (in PHP 7.4) to the handling of uninitialized properties in `serialize` have not made it into igbinary, so it no longer is a simple drop in replacement. This only removes igbinary as the default serializer, code can still opt-in through the first constructor argument. This may result in a performance regression on systems with igbinary as it would no longer be used by default. --- Marshaller/DefaultMarshaller.php | 8 +++----- Tests/Marshaller/DefaultMarshallerTest.php | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Marshaller/DefaultMarshaller.php b/Marshaller/DefaultMarshaller.php index 34bbeb89..02ebcfad 100644 --- a/Marshaller/DefaultMarshaller.php +++ b/Marshaller/DefaultMarshaller.php @@ -20,17 +20,15 @@ */ class DefaultMarshaller implements MarshallerInterface { - private bool $useIgbinarySerialize = true; + private bool $useIgbinarySerialize = false; private bool $throwOnSerializationFailure = false; public function __construct(?bool $useIgbinarySerialize = null, bool $throwOnSerializationFailure = false) { - if (null === $useIgbinarySerialize) { - $useIgbinarySerialize = \extension_loaded('igbinary') && version_compare('3.1.6', phpversion('igbinary'), '<='); - } elseif ($useIgbinarySerialize && (!\extension_loaded('igbinary') || version_compare('3.1.6', phpversion('igbinary'), '>'))) { + if ($useIgbinarySerialize && (!\extension_loaded('igbinary') || version_compare('3.1.6', phpversion('igbinary'), '>'))) { throw new CacheException(\extension_loaded('igbinary') ? 'Please upgrade the "igbinary" PHP extension to v3.1.6 or higher.' : 'The "igbinary" PHP extension is not loaded.'); } - $this->useIgbinarySerialize = $useIgbinarySerialize; + $this->useIgbinarySerialize = true === $useIgbinarySerialize; $this->throwOnSerializationFailure = $throwOnSerializationFailure; } diff --git a/Tests/Marshaller/DefaultMarshallerTest.php b/Tests/Marshaller/DefaultMarshallerTest.php index 45b79278..a5578d96 100644 --- a/Tests/Marshaller/DefaultMarshallerTest.php +++ b/Tests/Marshaller/DefaultMarshallerTest.php @@ -24,7 +24,27 @@ public function testSerialize() 'b' => function () {}, ]; - $expected = ['a' => \extension_loaded('igbinary') && (version_compare('3.1.6', phpversion('igbinary'), '<=')) ? igbinary_serialize(123) : serialize(123)]; + $expected = ['a' => serialize(123)]; + $this->assertSame($expected, $marshaller->marshall($values, $failed)); + $this->assertSame(['b'], $failed); + } + + /** + * @requires extension igbinary + */ + public function testIgbinarySerialize() + { + if (version_compare('3.1.6', phpversion('igbinary'), '>')) { + $this->markTestSkipped('igbinary needs to be v3.1.6 or higher.'); + } + + $marshaller = new DefaultMarshaller(true); + $values = [ + 'a' => 123, + 'b' => function () {}, + ]; + + $expected = ['a' => igbinary_serialize(123)]; $this->assertSame($expected, $marshaller->marshall($values, $failed)); $this->assertSame(['b'], $failed); } From f0c3d1e2fdca96862350105cfc2966e8404ee5c7 Mon Sep 17 00:00:00 2001 From: Marcin Nowak Date: Fri, 26 Jul 2024 11:11:18 +0200 Subject: [PATCH 11/44] [Cache] Add optional ClockInterface to ArrayAdapter --- Adapter/ArrayAdapter.php | 15 +++++++++++---- CHANGELOG.md | 5 +++++ Tests/Adapter/ArrayAdapterTest.php | 14 ++++++++++++++ composer.json | 1 + 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Adapter/ArrayAdapter.php b/Adapter/ArrayAdapter.php index 97be852a..7b923877 100644 --- a/Adapter/ArrayAdapter.php +++ b/Adapter/ArrayAdapter.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Cache\Adapter; use Psr\Cache\CacheItemInterface; +use Psr\Clock\ClockInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Symfony\Component\Cache\CacheItem; @@ -44,6 +45,7 @@ public function __construct( private bool $storeSerialized = true, private float $maxLifetime = 0, private int $maxItems = 0, + private ?ClockInterface $clock = null, ) { if (0 > $maxLifetime) { throw new InvalidArgumentException(\sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime)); @@ -94,7 +96,7 @@ public function delete(string $key): bool public function hasItem(mixed $key): bool { - if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) { + if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > $this->getCurrentTime()) { if ($this->maxItems) { // Move the item last in the storage $value = $this->values[$key]; @@ -129,7 +131,7 @@ public function getItems(array $keys = []): iterable { \assert(self::validateKeys($keys)); - return $this->generateItems($keys, microtime(true), self::$createCacheItem); + return $this->generateItems($keys, $this->getCurrentTime(), self::$createCacheItem); } public function deleteItem(mixed $key): bool @@ -159,7 +161,7 @@ public function save(CacheItemInterface $item): bool $value = $item["\0*\0value"]; $expiry = $item["\0*\0expiry"]; - $now = microtime(true); + $now = $this->getCurrentTime(); if (null !== $expiry) { if (!$expiry) { @@ -216,7 +218,7 @@ public function commit(): bool public function clear(string $prefix = ''): bool { if ('' !== $prefix) { - $now = microtime(true); + $now = $this->getCurrentTime(); foreach ($this->values as $key => $value) { if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || str_starts_with($key, $prefix)) { @@ -356,4 +358,9 @@ private function validateKeys(array $keys): bool return true; } + + private function getCurrentTime(): float + { + return $this->clock?->now()->format('U.u') ?? microtime(true); + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index cab9bf61..c473b468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.2 +--- + + * Add optional `Psr\Clock\ClockInterface` parameter to `ArrayAdapter` + 7.1 --- diff --git a/Tests/Adapter/ArrayAdapterTest.php b/Tests/Adapter/ArrayAdapterTest.php index c49cc319..7a223445 100644 --- a/Tests/Adapter/ArrayAdapterTest.php +++ b/Tests/Adapter/ArrayAdapterTest.php @@ -14,6 +14,7 @@ use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Tests\Fixtures\TestEnum; +use Symfony\Component\Clock\MockClock; /** * @group time-sensitive @@ -102,4 +103,17 @@ public function testEnum() $this->assertSame(TestEnum::Foo, $cache->getItem('foo')->get()); } + + public function testClockAware() + { + $clock = new MockClock(); + $cache = new ArrayAdapter(10, false, 0, 0, $clock); + + $cache->save($cache->getItem('foo')); + $this->assertTrue($cache->hasItem('foo')); + + $clock->modify('+11 seconds'); + + $this->assertFalse($cache->hasItem('foo')); + } } diff --git a/composer.json b/composer.json index d537037a..bdb461be 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/filesystem": "^6.4|^7.0", From 9def9f092e08e2f2befea944490861954b853b5b Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Fri, 19 Jul 2024 13:24:25 +0200 Subject: [PATCH 12/44] [Cache][Config][Console][DependencyInjection][FrameworkBundle] Remove dead code and useless casts --- Adapter/AbstractTagAwareAdapter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adapter/AbstractTagAwareAdapter.php b/Adapter/AbstractTagAwareAdapter.php index a1af6141..822c30f0 100644 --- a/Adapter/AbstractTagAwareAdapter.php +++ b/Adapter/AbstractTagAwareAdapter.php @@ -186,7 +186,7 @@ public function commit(): bool $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData); } catch (\Exception $e) { } - if (true === $e || [] === $e) { + if ([] === $e) { continue; } if (\is_array($e) || 1 === \count($values)) { @@ -213,7 +213,7 @@ public function commit(): bool $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData); } catch (\Exception $e) { } - if (true === $e || [] === $e) { + if ([] === $e) { continue; } $ok = false; From 53d1cf0fce3576cabae8f122f4e7c98acf7a4526 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 29 Jul 2024 09:00:38 +0200 Subject: [PATCH 13/44] document igbinary changes in the Cache component --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c473b468..7f7cfa42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 7.2 --- + * `igbinary_serialize()` is not used by default when the igbinary extension is installed * Add optional `Psr\Clock\ClockInterface` parameter to `ArrayAdapter` 7.1 From bf7c8969a16bb6496a94fbd47b3ddbe9069abe0b Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 5 Aug 2024 09:12:25 +0200 Subject: [PATCH 14/44] Fix multiple CS errors --- Adapter/PhpArrayAdapter.php | 2 +- Tests/Traits/RedisTraitTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Adapter/PhpArrayAdapter.php b/Adapter/PhpArrayAdapter.php index 81d1ac81..8047a8a2 100644 --- a/Adapter/PhpArrayAdapter.php +++ b/Adapter/PhpArrayAdapter.php @@ -321,7 +321,7 @@ public function warmUp(array $values): array $dump .= "\n], [\n\n{$dumpedValues}\n]];\n"; - $tmpFile = tempnam(dirname($this->file), basename($this->file)); + $tmpFile = tempnam(\dirname($this->file), basename($this->file)); file_put_contents($tmpFile, $dump); @chmod($tmpFile, 0666 & ~umask()); diff --git a/Tests/Traits/RedisTraitTest.php b/Tests/Traits/RedisTraitTest.php index bdf85f82..9d3ad34e 100644 --- a/Tests/Traits/RedisTraitTest.php +++ b/Tests/Traits/RedisTraitTest.php @@ -200,11 +200,11 @@ public static function provideInvalidDbIndexDsnParameter(): array { return [ [ - 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/abc' + 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/abc', ], [ - 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/3?dbindex=6' - ] + 'redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST').'/3?dbindex=6', + ], ]; } } From dd83552f8e5decea4c113654b22416cc9a7ae9c8 Mon Sep 17 00:00:00 2001 From: Roy de Vos Burchart Date: Thu, 1 Aug 2024 17:21:17 +0200 Subject: [PATCH 15/44] Code style change in `@PER-CS2.0` affecting `@Symfony` (parentheses for anonymous classes) --- Tests/Messenger/EarlyExpirationDispatcherTest.php | 4 ++-- Tests/Messenger/EarlyExpirationHandlerTest.php | 2 +- Tests/Messenger/EarlyExpirationMessageTest.php | 2 +- Tests/Traits/RedisTraitTest.php | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Tests/Messenger/EarlyExpirationDispatcherTest.php b/Tests/Messenger/EarlyExpirationDispatcherTest.php index 47331bba..caca6fe7 100644 --- a/Tests/Messenger/EarlyExpirationDispatcherTest.php +++ b/Tests/Messenger/EarlyExpirationDispatcherTest.php @@ -41,7 +41,7 @@ public function testFetch() $item = $pool->getItem('foo'); - $computationService = new class() { + $computationService = new class { public function __invoke(CacheItem $item) { return 123; @@ -90,7 +90,7 @@ public function testEarlyExpiration() $pool->save($item->set(789)); $item = $pool->getItem('foo'); - $computationService = new class() { + $computationService = new class { public function __invoke(CacheItem $item) { return 123; diff --git a/Tests/Messenger/EarlyExpirationHandlerTest.php b/Tests/Messenger/EarlyExpirationHandlerTest.php index 6b842545..963215df 100644 --- a/Tests/Messenger/EarlyExpirationHandlerTest.php +++ b/Tests/Messenger/EarlyExpirationHandlerTest.php @@ -38,7 +38,7 @@ public function testHandle() $item = $pool->getItem('foo'); $item->set(234); - $computationService = new class() implements CallbackInterface { + $computationService = new class implements CallbackInterface { public function __invoke(CacheItemInterface $item, bool &$save): mixed { usleep(30000); diff --git a/Tests/Messenger/EarlyExpirationMessageTest.php b/Tests/Messenger/EarlyExpirationMessageTest.php index 9d8a643d..ec8ea60f 100644 --- a/Tests/Messenger/EarlyExpirationMessageTest.php +++ b/Tests/Messenger/EarlyExpirationMessageTest.php @@ -27,7 +27,7 @@ public function testCreate() $item = $pool->getItem('foo'); $item->set(234); - $computationService = new class() { + $computationService = new class { public function __invoke(CacheItem $item) { return 123; diff --git a/Tests/Traits/RedisTraitTest.php b/Tests/Traits/RedisTraitTest.php index bdf85f82..81a29e47 100644 --- a/Tests/Traits/RedisTraitTest.php +++ b/Tests/Traits/RedisTraitTest.php @@ -32,7 +32,7 @@ public function testCreateConnection(string $dsn, string $expectedClass) self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); } - $mock = new class() { + $mock = new class { use RedisTrait; }; $connection = $mock::createConnection($dsn); @@ -46,7 +46,7 @@ public function testUrlDecodeParameters() self::markTestSkipped('REDIS_AUTHENTICATED_HOST env var is not defined.'); } - $mock = new class() { + $mock = new class { use RedisTrait; }; $connection = $mock::createConnection('redis://:p%40ssword@'.getenv('REDIS_AUTHENTICATED_HOST')); @@ -105,7 +105,7 @@ public function testPconnectSelectsCorrectDatabase() } try { - $mock = new class() { + $mock = new class { use RedisTrait; }; @@ -143,7 +143,7 @@ public function testDbIndexDsnParameter(string $dsn, int $expectedDb) self::markTestSkipped('REDIS_AUTHENTICATED_HOST env var is not defined.'); } - $mock = new class () { + $mock = new class { use RedisTrait; }; $connection = $mock::createConnection($dsn); @@ -190,7 +190,7 @@ public function testInvalidDbIndexDsnParameter(string $dsn) } $this->expectException(InvalidArgumentException::class); - $mock = new class () { + $mock = new class { use RedisTrait; }; $mock::createConnection($dsn); From 4c2dce692db1fdb8d4f78df7b1a7c76047576399 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 18 Sep 2024 13:33:46 +0200 Subject: [PATCH 16/44] Miscellaneous tests improvements --- .../DataCollector/CacheDataCollectorTest.php | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/Tests/DataCollector/CacheDataCollectorTest.php b/Tests/DataCollector/CacheDataCollectorTest.php index a00954b6..bb102363 100644 --- a/Tests/DataCollector/CacheDataCollectorTest.php +++ b/Tests/DataCollector/CacheDataCollectorTest.php @@ -26,11 +26,11 @@ public function testEmptyDataCollector() { $statistics = $this->getCacheDataCollectorStatisticsFromEvents([]); - $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 0, 'calls'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['calls'], 'calls'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['reads'], 'reads'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['hits'], 'hits'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['misses'], 'misses'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['writes'], 'writes'); } public function testOneEventDataCollector() @@ -43,11 +43,11 @@ public function testOneEventDataCollector() $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); - $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 1, 'misses'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['calls'], 'calls'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['reads'], 'reads'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['hits'], 'hits'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['misses'], 'misses'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['writes'], 'writes'); } public function testHitedEventDataCollector() @@ -62,11 +62,11 @@ public function testHitedEventDataCollector() $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); - $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 1, 'misses'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['calls'], 'calls'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['reads'], 'reads'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['hits'], 'hits'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['misses'], 'misses'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['writes'], 'writes'); } public function testSavedEventDataCollector() @@ -78,11 +78,11 @@ public function testSavedEventDataCollector() $statistics = $this->getCacheDataCollectorStatisticsFromEvents([$traceableAdapterEvent]); - $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 0, 'reads'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 1, 'writes'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['calls'], 'calls'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['reads'], 'reads'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['hits'], 'hits'); + $this->assertSame(0, $statistics[self::INSTANCE_NAME]['misses'], 'misses'); + $this->assertSame(1, $statistics[self::INSTANCE_NAME]['writes'], 'writes'); } public function testCollectBeforeEnd() @@ -100,8 +100,8 @@ public function testCollectBeforeEnd() $stats = $collector->getStatistics(); $this->assertGreaterThan(0, $stats[self::INSTANCE_NAME]['time']); - $this->assertEquals($stats[self::INSTANCE_NAME]['hits'], 0, 'hits'); - $this->assertEquals($stats[self::INSTANCE_NAME]['misses'], 1, 'misses'); + $this->assertSame(0, $stats[self::INSTANCE_NAME]['hits'], 'hits'); + $this->assertSame(1, $stats[self::INSTANCE_NAME]['misses'], 'misses'); } private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents) From 02c94bfbb08c03429cffd1eedf8826511f596035 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 24 Sep 2024 13:28:07 +0200 Subject: [PATCH 17/44] Remove useless parent method calls in tests --- Tests/Adapter/AdapterTestCase.php | 2 -- Tests/Psr16CacheProxyTest.php | 2 -- Tests/Psr16CacheTest.php | 2 -- Tests/Psr16CacheWithExternalAdapter.php | 2 -- 4 files changed, 8 deletions(-) diff --git a/Tests/Adapter/AdapterTestCase.php b/Tests/Adapter/AdapterTestCase.php index 8c4b4048..da430296 100644 --- a/Tests/Adapter/AdapterTestCase.php +++ b/Tests/Adapter/AdapterTestCase.php @@ -23,8 +23,6 @@ abstract class AdapterTestCase extends CachePoolTest { protected function setUp(): void { - parent::setUp(); - if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; } diff --git a/Tests/Psr16CacheProxyTest.php b/Tests/Psr16CacheProxyTest.php index 25515a02..c3d2d8d5 100644 --- a/Tests/Psr16CacheProxyTest.php +++ b/Tests/Psr16CacheProxyTest.php @@ -21,8 +21,6 @@ class Psr16CacheProxyTest extends SimpleCacheTest { protected function setUp(): void { - parent::setUp(); - try { \assert(false === true, new \Exception()); $this->skippedTests['testGetInvalidKeys'] = diff --git a/Tests/Psr16CacheTest.php b/Tests/Psr16CacheTest.php index 322796c3..b5a1fe48 100644 --- a/Tests/Psr16CacheTest.php +++ b/Tests/Psr16CacheTest.php @@ -24,8 +24,6 @@ class Psr16CacheTest extends SimpleCacheTest { protected function setUp(): void { - parent::setUp(); - if (\array_key_exists('testPrune', $this->skippedTests)) { return; } diff --git a/Tests/Psr16CacheWithExternalAdapter.php b/Tests/Psr16CacheWithExternalAdapter.php index e018a276..39eba832 100644 --- a/Tests/Psr16CacheWithExternalAdapter.php +++ b/Tests/Psr16CacheWithExternalAdapter.php @@ -23,8 +23,6 @@ class Psr16CacheWithExternalAdapter extends SimpleCacheTest { protected function setUp(): void { - parent::setUp(); - $this->skippedTests['testSetTtl'] = $this->skippedTests['testSetMultipleTtl'] = 'The ExternalAdapter test class does not support TTLs.'; } From 5e0bc576c566c05b1d483abbcadaa86967027661 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 1 Oct 2024 15:17:35 +0200 Subject: [PATCH 18/44] Remove a few unnecessary full qualifier --- Tests/Adapter/MemcachedAdapterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Adapter/MemcachedAdapterTest.php b/Tests/Adapter/MemcachedAdapterTest.php index 88950042..b0edfa1e 100644 --- a/Tests/Adapter/MemcachedAdapterTest.php +++ b/Tests/Adapter/MemcachedAdapterTest.php @@ -253,7 +253,7 @@ public function testKeyEncoding() $pool = $this->createCachePool(0, null, $namespace); /** - * Choose a key that is below {@see \Symfony\Component\Cache\Adapter\MemcachedAdapter::$maxIdLength} so that + * Choose a key that is below {@see MemcachedAdapter::$maxIdLength} so that * {@see \Symfony\Component\Cache\Traits\AbstractTrait::getId()} does not shorten the key but choose special * characters that would be encoded and therefore increase the key length over the Memcached limit. */ From 2b2bf5f2f280ee0db38842ac27649d0bebd5544f Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Fri, 18 Oct 2024 16:04:52 +0200 Subject: [PATCH 19/44] Remove always true/false occurrences --- Adapter/TagAwareAdapter.php | 6 ++---- Traits/FilesystemCommonTrait.php | 1 - Traits/RedisTrait.php | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Adapter/TagAwareAdapter.php b/Adapter/TagAwareAdapter.php index 34082db1..53c98904 100644 --- a/Adapter/TagAwareAdapter.php +++ b/Adapter/TagAwareAdapter.php @@ -207,12 +207,10 @@ public function clear(string $prefix = ''): bool unset($this->deferred[$key]); } } - } else { - $this->deferred = []; - } - if ($this->pool instanceof AdapterInterface) { return $this->pool->clear($prefix); + } else { + $this->deferred = []; } return $this->pool->clear(); diff --git a/Traits/FilesystemCommonTrait.php b/Traits/FilesystemCommonTrait.php index 98658a71..98e0d3ec 100644 --- a/Traits/FilesystemCommonTrait.php +++ b/Traits/FilesystemCommonTrait.php @@ -108,7 +108,6 @@ private function write(string $file, string $data, ?int $expiresAt = null): bool if ('\\' === \DIRECTORY_SEPARATOR) { $success = copy($tmp, $file); - $unlink = true; } else { $success = rename($tmp, $file); $unlink = !$success; diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 75a2f36e..d885c097 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -199,7 +199,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra \extension_loaded('relay') => Relay::class, default => \Predis\Client::class, }, - 1 < \count($hosts) && \extension_loaded('redis') => 1 < \count($hosts) ? \RedisArray::class : \Redis::class, + 1 < \count($hosts) && \extension_loaded('redis') => \RedisArray::class, \extension_loaded('redis') => \Redis::class, \extension_loaded('relay') => Relay::class, default => \Predis\Client::class, @@ -614,7 +614,7 @@ private function pipeline(\Closure $generator, ?object $redis = null): \Generato } }); } elseif ($redis instanceof \RedisArray) { - $connections = $results = $ids = []; + $connections = $results = []; foreach ($generator() as $command => $args) { $id = 'eval' === $command ? $args[1][0] : $args[0]; if (!isset($connections[$h = $redis->_target($id)])) { From 2c926bc348184b4b235f2200fcbe8fcf3c8c5b8a Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 16 Nov 2024 15:49:06 +0100 Subject: [PATCH 20/44] Proofread UPGRADE guide --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7cfa42..038915c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ CHANGELOG 7.2 --- - * `igbinary_serialize()` is not used by default when the igbinary extension is installed + * `igbinary_serialize()` is no longer used instead of `serialize()` by default when the igbinary extension is installed, + due to behavior compatibilities between the two * Add optional `Psr\Clock\ClockInterface` parameter to `ArrayAdapter` 7.1 From e7e983596b744c4539f31e79b0350a6cf5878a20 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Thu, 5 Dec 2024 00:17:16 +0100 Subject: [PATCH 21/44] chore: fix CS --- Traits/Relay/MoveTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Traits/Relay/MoveTrait.php b/Traits/Relay/MoveTrait.php index 1f1b84c0..18086f61 100644 --- a/Traits/Relay/MoveTrait.php +++ b/Traits/Relay/MoveTrait.php @@ -33,12 +33,12 @@ public function lmove($srckey, $dstkey, $srcpos, $dstpos): mixed */ trait MoveTrait { - public function blmove($srckey, $dstkey, $srcpos, $dstpos, $timeout): \Relay\Relay|false|null|string + public function blmove($srckey, $dstkey, $srcpos, $dstpos, $timeout): \Relay\Relay|false|string|null { return $this->initializeLazyObject()->blmove(...\func_get_args()); } - public function lmove($srckey, $dstkey, $srcpos, $dstpos): \Relay\Relay|false|null|string + public function lmove($srckey, $dstkey, $srcpos, $dstpos): \Relay\Relay|false|string|null { return $this->initializeLazyObject()->lmove(...\func_get_args()); } From 916032b874b9881c6b91cf9ab05c2cb60459156d Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Wed, 11 Dec 2024 14:08:35 +0100 Subject: [PATCH 22/44] chore: PHP CS Fixer fixes --- Tests/Traits/RedisProxiesTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index 1e17b474..0be40602 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -34,7 +34,7 @@ public function testRedisProxy($class) $expected = substr($proxy, 0, 2 + strpos($proxy, '}')); $methods = []; - foreach ((new \ReflectionClass(sprintf('Symfony\Component\Cache\Traits\\%s%dProxy', $class, $version)))->getMethods() as $method) { + foreach ((new \ReflectionClass(\sprintf('Symfony\Component\Cache\Traits\\%s%dProxy', $class, $version)))->getMethods() as $method) { if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name)) { continue; } From 9c60a16fd4a859f4ac5ff056101f7514aacc6e86 Mon Sep 17 00:00:00 2001 From: ywisax Date: Fri, 20 Dec 2024 01:55:36 +0800 Subject: [PATCH 23/44] Update PhpFilesAdapter.php, remove goto statement The goto statement can make the code's flow difficult to follow. PHP code is typically expected to have a more linear and understandable structure. For example, when using goto, it can jump from one part of the code to another in a non - sequential manner. This can lead to confusion for developers who are trying to understand the program's logic, especially in larger codebases. --- Adapter/PhpFilesAdapter.php | 94 ++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Adapter/PhpFilesAdapter.php b/Adapter/PhpFilesAdapter.php index e550276d..efb43440 100644 --- a/Adapter/PhpFilesAdapter.php +++ b/Adapter/PhpFilesAdapter.php @@ -104,65 +104,65 @@ protected function doFetch(array $ids): iterable } $values = []; - begin: - $getExpiry = false; - - foreach ($ids as $id) { - if (null === $value = $this->values[$id] ?? null) { - $missingIds[] = $id; - } elseif ('N;' === $value) { - $values[$id] = null; - } elseif (!\is_object($value)) { - $values[$id] = $value; - } elseif (!$value instanceof LazyValue) { - $values[$id] = $value(); - } elseif (false === $values[$id] = include $value->file) { - unset($values[$id], $this->values[$id]); - $missingIds[] = $id; + while (true) { + $getExpiry = false; + + foreach ($ids as $id) { + if (null === $value = $this->values[$id] ?? null) { + $missingIds[] = $id; + } elseif ('N;' === $value) { + $values[$id] = null; + } elseif (!\is_object($value)) { + $values[$id] = $value; + } elseif (!$value instanceof LazyValue) { + $values[$id] = $value(); + } elseif (false === $values[$id] = include $value->file) { + unset($values[$id], $this->values[$id]); + $missingIds[] = $id; + } + if (!$this->appendOnly) { + unset($this->values[$id]); + } } - if (!$this->appendOnly) { - unset($this->values[$id]); + + if (!$missingIds) { + return $values; } - } - if (!$missingIds) { - return $values; - } + set_error_handler($this->includeHandler); + try { + $getExpiry = true; - set_error_handler($this->includeHandler); - try { - $getExpiry = true; + foreach ($missingIds as $k => $id) { + try { + $file = $this->files[$id] ??= $this->getFile($id); - foreach ($missingIds as $k => $id) { - try { - $file = $this->files[$id] ??= $this->getFile($id); + if (isset(self::$valuesCache[$file])) { + [$expiresAt, $this->values[$id]] = self::$valuesCache[$file]; + } elseif (\is_array($expiresAt = include $file)) { + if ($this->appendOnly) { + self::$valuesCache[$file] = $expiresAt; + } - if (isset(self::$valuesCache[$file])) { - [$expiresAt, $this->values[$id]] = self::$valuesCache[$file]; - } elseif (\is_array($expiresAt = include $file)) { - if ($this->appendOnly) { - self::$valuesCache[$file] = $expiresAt; + [$expiresAt, $this->values[$id]] = $expiresAt; + } elseif ($now < $expiresAt) { + $this->values[$id] = new LazyValue($file); } - [$expiresAt, $this->values[$id]] = $expiresAt; - } elseif ($now < $expiresAt) { - $this->values[$id] = new LazyValue($file); - } - - if ($now >= $expiresAt) { - unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]); + if ($now >= $expiresAt) { + unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]); + } + } catch (\ErrorException $e) { + unset($missingIds[$k]); } - } catch (\ErrorException $e) { - unset($missingIds[$k]); } + } finally { + restore_error_handler(); } - } finally { - restore_error_handler(); - } - $ids = $missingIds; - $missingIds = []; - goto begin; + $ids = $missingIds; + $missingIds = []; + } } protected function doHave(string $id): bool From 387a540540946554e83c1184584928a0a3d2bf8f Mon Sep 17 00:00:00 2001 From: DemigodCode Date: Tue, 11 Feb 2025 13:06:06 +0100 Subject: [PATCH 24/44] [Cache] Tests for Redis Replication with cache --- .../PredisRedisReplicationAdapterTest.php | 29 +++++++++ .../Adapter/PredisReplicationAdapterTest.php | 24 +++++++ .../PredisTagAwareReplicationAdapterTest.php | 37 +++++++++++ Tests/Adapter/RedisReplicationAdapterTest.php | 65 +++++++++++++++++++ Traits/RedisTrait.php | 14 +++- 5 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 Tests/Adapter/PredisRedisReplicationAdapterTest.php create mode 100644 Tests/Adapter/PredisReplicationAdapterTest.php create mode 100644 Tests/Adapter/PredisTagAwareReplicationAdapterTest.php create mode 100644 Tests/Adapter/RedisReplicationAdapterTest.php diff --git a/Tests/Adapter/PredisRedisReplicationAdapterTest.php b/Tests/Adapter/PredisRedisReplicationAdapterTest.php new file mode 100644 index 00000000..55272774 --- /dev/null +++ b/Tests/Adapter/PredisRedisReplicationAdapterTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\RedisAdapter; + +/** + * @group integration + */ +class PredisRedisReplicationAdapterTest extends AbstractRedisAdapterTestCase +{ + public static function setUpBeforeClass(): void + { + if (!$hosts = getenv('REDIS_REPLICATION_HOSTS')) { + self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.'); + } + + self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).'][alias]=master', ['class' => \Predis\Client::class, 'prefix' => 'prefix_']); + } +} diff --git a/Tests/Adapter/PredisReplicationAdapterTest.php b/Tests/Adapter/PredisReplicationAdapterTest.php new file mode 100644 index 00000000..4add9d5f --- /dev/null +++ b/Tests/Adapter/PredisReplicationAdapterTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +/** + * @group integration + */ +class PredisReplicationAdapterTest extends AbstractRedisAdapterTestCase +{ + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + self::$redis = new \Predis\Client(array_combine(['host', 'port'], explode(':', getenv('REDIS_HOST')) + [1 => 6379]), ['prefix' => 'prefix_']); + } +} diff --git a/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php b/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php new file mode 100644 index 00000000..4d8651ce --- /dev/null +++ b/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter; + +/** + * @group integration + */ +class PredisTagAwareReplicationAdapterTest extends PredisReplicationAdapterTest +{ + use TagAwareTestTrait; + + protected function setUp(): void + { + parent::setUp(); + $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; + } + + public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface + { + $this->assertInstanceOf(\Predis\Client::class, self::$redis); + $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + + return $adapter; + } +} diff --git a/Tests/Adapter/RedisReplicationAdapterTest.php b/Tests/Adapter/RedisReplicationAdapterTest.php new file mode 100644 index 00000000..e4174505 --- /dev/null +++ b/Tests/Adapter/RedisReplicationAdapterTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Adapter\RedisAdapter; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\Traits\RedisClusterProxy; + +/** + * @group integration + */ +class RedisReplicationAdapterTest extends AbstractRedisAdapterTestCase +{ + public static function setUpBeforeClass(): void + { + if (!$hosts = getenv('REDIS_REPLICATION_HOSTS')) { + self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.'); + } + + self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).'][alias]=master', ['lazy' => true]); + self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_'); + } + + 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); + $adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + + return $adapter; + } + + /** + * @dataProvider provideFailedCreateConnection + */ + public function testFailedCreateConnection(string $dsn) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Redis connection '); + RedisAdapter::createConnection($dsn); + } + + public static function provideFailedCreateConnection(): array + { + return [ + ['redis://localhost:1234'], + ['redis://foo@localhost?role=master'], + ['redis://localhost/123?role=master'], + ]; + } +} diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index fc8f5cec..2ebaed16 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -17,6 +17,7 @@ use Predis\Connection\Aggregate\ReplicationInterface; use Predis\Connection\Cluster\ClusterInterface as Predis2ClusterInterface; use Predis\Connection\Cluster\RedisCluster as Predis2RedisCluster; +use Predis\Connection\Replication\ReplicationInterface as Predis2ReplicationInterface; use Predis\Response\ErrorInterface; use Predis\Response\Status; use Relay\Relay; @@ -473,9 +474,16 @@ protected function doClear(string $namespace): bool $cleared = true; $hosts = $this->getHosts(); $host = reset($hosts); - if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) { - // Predis supports info command only on the master in replication environments - $hosts = [$host->getClientFor('master')]; + if ($host instanceof \Predis\Client) { + $connection = $host->getConnection(); + + if ($connection instanceof ReplicationInterface) { + $hosts = [$host->getClientFor('master')]; + } elseif ($connection instanceof Predis2ReplicationInterface) { + $connection->switchToMaster(); + + $hosts = [$host]; + } } foreach ($hosts as $host) { From f07faaba7d2167096ac63cd74a0235218cef5e52 Mon Sep 17 00:00:00 2001 From: DemigodCode Date: Fri, 14 Feb 2025 23:53:43 +0100 Subject: [PATCH 25/44] fix integration tests --- .../PredisRedisReplicationAdapterTest.php | 2 +- .../Adapter/PredisReplicationAdapterTest.php | 18 ++++- .../PredisTagAwareReplicationAdapterTest.php | 37 ----------- Tests/Adapter/RedisReplicationAdapterTest.php | 65 ------------------- 4 files changed, 18 insertions(+), 104 deletions(-) delete mode 100644 Tests/Adapter/PredisTagAwareReplicationAdapterTest.php delete mode 100644 Tests/Adapter/RedisReplicationAdapterTest.php diff --git a/Tests/Adapter/PredisRedisReplicationAdapterTest.php b/Tests/Adapter/PredisRedisReplicationAdapterTest.php index 55272774..cda92af8 100644 --- a/Tests/Adapter/PredisRedisReplicationAdapterTest.php +++ b/Tests/Adapter/PredisRedisReplicationAdapterTest.php @@ -24,6 +24,6 @@ public static function setUpBeforeClass(): void self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.'); } - self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).'][alias]=master', ['class' => \Predis\Client::class, 'prefix' => 'prefix_']); + self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).'][role]=master', ['replication' => 'predis', 'class' => \Predis\Client::class, 'prefix' => 'prefix_']); } } diff --git a/Tests/Adapter/PredisReplicationAdapterTest.php b/Tests/Adapter/PredisReplicationAdapterTest.php index 4add9d5f..28af1b5b 100644 --- a/Tests/Adapter/PredisReplicationAdapterTest.php +++ b/Tests/Adapter/PredisReplicationAdapterTest.php @@ -19,6 +19,22 @@ class PredisReplicationAdapterTest extends AbstractRedisAdapterTestCase public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); - self::$redis = new \Predis\Client(array_combine(['host', 'port'], explode(':', getenv('REDIS_HOST')) + [1 => 6379]), ['prefix' => 'prefix_']); + + if (!$hosts = getenv('REDIS_REPLICATION_HOSTS')) { + self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.'); + } + + $hosts = explode(' ', getenv('REDIS_REPLICATION_HOSTS')); + $lastArrayKey = array_key_last($hosts); + $hostTable = []; + foreach($hosts as $key => $host) { + $hostInformation = array_combine(['host', 'port'], explode(':', $host)); + if($lastArrayKey === $key) { + $hostInformation['role'] = 'master'; + } + $hostTable[] = $hostInformation; + } + + self::$redis = new \Predis\Client($hostTable, ['replication' => 'predis', 'prefix' => 'prefix_']); } } diff --git a/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php b/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php deleted file mode 100644 index 4d8651ce..00000000 --- a/Tests/Adapter/PredisTagAwareReplicationAdapterTest.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter; - -/** - * @group integration - */ -class PredisTagAwareReplicationAdapterTest extends PredisReplicationAdapterTest -{ - use TagAwareTestTrait; - - protected function setUp(): void - { - parent::setUp(); - $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; - } - - public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface - { - $this->assertInstanceOf(\Predis\Client::class, self::$redis); - $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - - return $adapter; - } -} diff --git a/Tests/Adapter/RedisReplicationAdapterTest.php b/Tests/Adapter/RedisReplicationAdapterTest.php deleted file mode 100644 index e4174505..00000000 --- a/Tests/Adapter/RedisReplicationAdapterTest.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Adapter\RedisAdapter; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Traits\RedisClusterProxy; - -/** - * @group integration - */ -class RedisReplicationAdapterTest extends AbstractRedisAdapterTestCase -{ - public static function setUpBeforeClass(): void - { - if (!$hosts = getenv('REDIS_REPLICATION_HOSTS')) { - self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.'); - } - - self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).'][alias]=master', ['lazy' => true]); - self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_'); - } - - 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); - $adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - - return $adapter; - } - - /** - * @dataProvider provideFailedCreateConnection - */ - public function testFailedCreateConnection(string $dsn) - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Redis connection '); - RedisAdapter::createConnection($dsn); - } - - public static function provideFailedCreateConnection(): array - { - return [ - ['redis://localhost:1234'], - ['redis://foo@localhost?role=master'], - ['redis://localhost/123?role=master'], - ]; - } -} From 342e87b15ac02e4b4f0924ddc368e75d5262aab3 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 26 Feb 2025 09:12:21 +0100 Subject: [PATCH 26/44] [Cache] Fix `PredisAdapter` tests --- Tests/Adapter/PredisAdapterTest.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Tests/Adapter/PredisAdapterTest.php b/Tests/Adapter/PredisAdapterTest.php index 5fdd35ca..d9afd85a 100644 --- a/Tests/Adapter/PredisAdapterTest.php +++ b/Tests/Adapter/PredisAdapterTest.php @@ -36,6 +36,8 @@ public function testCreateConnection() $this->assertInstanceOf(StreamConnection::class, $connection); $redisHost = explode(':', $redisHost); + $connectionParameters = $connection->getParameters()->toArray(); + $params = [ 'scheme' => 'tcp', 'host' => $redisHost[0], @@ -46,7 +48,12 @@ public function testCreateConnection() 'tcp_nodelay' => true, 'database' => '1', ]; - $this->assertSame($params, $connection->getParameters()->toArray()); + + if (isset($connectionParameters['conn_uid'])) { + $params['conn_uid'] = $connectionParameters['conn_uid']; // if present, the value cannot be predicted + } + + $this->assertSame($params, $connectionParameters); } public function testCreateSslConnection() @@ -60,6 +67,8 @@ public function testCreateSslConnection() $this->assertInstanceOf(StreamConnection::class, $connection); $redisHost = explode(':', $redisHost); + $connectionParameters = $connection->getParameters()->toArray(); + $params = [ 'scheme' => 'tls', 'host' => $redisHost[0], @@ -71,7 +80,12 @@ public function testCreateSslConnection() 'tcp_nodelay' => true, 'database' => '1', ]; - $this->assertSame($params, $connection->getParameters()->toArray()); + + if (isset($connectionParameters['conn_uid'])) { + $params['conn_uid'] = $connectionParameters['conn_uid']; // if present, the value cannot be predicted + } + + $this->assertSame($params, $connectionParameters); } public function testAclUserPasswordAuth() From 27f5a82f15403ceca773d47c1620e3ebd8dfa1a7 Mon Sep 17 00:00:00 2001 From: COMBROUSE Dimitri Date: Sun, 23 Feb 2025 12:00:48 +0100 Subject: [PATCH 27/44] fix cache data collector on late collect --- DataCollector/CacheDataCollector.php | 20 +++++++++---------- .../DataCollector/CacheDataCollectorTest.php | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/DataCollector/CacheDataCollector.php b/DataCollector/CacheDataCollector.php index b9bcdaf1..c7f2381e 100644 --- a/DataCollector/CacheDataCollector.php +++ b/DataCollector/CacheDataCollector.php @@ -38,15 +38,7 @@ public function addInstance(string $name, TraceableAdapter $instance): void public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { - $empty = ['calls' => [], 'adapters' => [], 'config' => [], 'options' => [], 'statistics' => []]; - $this->data = ['instances' => $empty, 'total' => $empty]; - foreach ($this->instances as $name => $instance) { - $this->data['instances']['calls'][$name] = $instance->getCalls(); - $this->data['instances']['adapters'][$name] = get_debug_type($instance->getPool()); - } - - $this->data['instances']['statistics'] = $this->calculateStatistics(); - $this->data['total']['statistics'] = $this->calculateTotalStatistics(); + $this->lateCollect(); } public function reset(): void @@ -59,7 +51,15 @@ public function reset(): void public function lateCollect(): void { - $this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']); + $empty = ['calls' => [], 'adapters' => [], 'config' => [], 'options' => [], 'statistics' => []]; + $this->data = ['instances' => $empty, 'total' => $empty]; + foreach ($this->instances as $name => $instance) { + $this->data['instances']['calls'][$name] = $instance->getCalls(); + $this->data['instances']['adapters'][$name] = get_debug_type($instance->getPool()); + } + + $this->data['instances']['statistics'] = $this->calculateStatistics(); + $this->data['total']['statistics'] = $this->calculateTotalStatistics(); } public function getName(): string diff --git a/Tests/DataCollector/CacheDataCollectorTest.php b/Tests/DataCollector/CacheDataCollectorTest.php index a00954b6..68563bfc 100644 --- a/Tests/DataCollector/CacheDataCollectorTest.php +++ b/Tests/DataCollector/CacheDataCollectorTest.php @@ -104,6 +104,26 @@ public function testCollectBeforeEnd() $this->assertEquals($stats[self::INSTANCE_NAME]['misses'], 1, 'misses'); } + public function testLateCollect() + { + $adapter = new TraceableAdapter(new NullAdapter()); + + $collector = new CacheDataCollector(); + $collector->addInstance(self::INSTANCE_NAME, $adapter); + + $adapter->get('foo', function () use ($collector) { + $collector->lateCollect(); + + return 123; + }); + + $stats = $collector->getStatistics(); + $this->assertGreaterThan(0, $stats[self::INSTANCE_NAME]['time']); + $this->assertEquals($stats[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($stats[self::INSTANCE_NAME]['misses'], 1, 'misses'); + $this->assertEquals($stats[self::INSTANCE_NAME]['calls'], 1, 'calls'); + } + private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents) { $traceableAdapterMock = $this->createMock(TraceableAdapter::class); From ff1c4cc7d65b52f2ec238e5b3d0fdbab67380354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Bok?= Date: Tue, 25 Feb 2025 22:26:37 +0100 Subject: [PATCH 28/44] [Cache] Add `\Relay\Cluster` support --- Adapter/RedisAdapter.php | 2 +- Adapter/RedisTagAwareAdapter.php | 6 +- CHANGELOG.md | 5 + .../Adapter/AbstractRedisAdapterTestCase.php | 3 +- .../RedisTagAwareRelayClusterAdapterTest.php | 40 + Tests/Adapter/RelayClusterAdapterTest.php | 68 + Tests/Traits/RedisProxiesTest.php | 50 + Traits/RedisTrait.php | 109 +- Traits/RelayClusterProxy.php | 1203 +++++++++++++++++ 9 files changed, 1475 insertions(+), 11 deletions(-) create mode 100644 Tests/Adapter/RedisTagAwareRelayClusterAdapterTest.php create mode 100644 Tests/Adapter/RelayClusterAdapterTest.php create mode 100644 Traits/RelayClusterProxy.php diff --git a/Adapter/RedisAdapter.php b/Adapter/RedisAdapter.php index e33f2f65..f31f0d7d 100644 --- a/Adapter/RedisAdapter.php +++ b/Adapter/RedisAdapter.php @@ -18,7 +18,7 @@ class RedisAdapter extends AbstractAdapter { use RedisTrait; - public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Relay\Relay $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null) + public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Relay\Relay|\Relay\Cluster $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null) { $this->init($redis, $namespace, $defaultLifetime, $marshaller); } diff --git a/Adapter/RedisTagAwareAdapter.php b/Adapter/RedisTagAwareAdapter.php index 7b282375..a887f29a 100644 --- a/Adapter/RedisTagAwareAdapter.php +++ b/Adapter/RedisTagAwareAdapter.php @@ -60,7 +60,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter private string $redisEvictionPolicy; public function __construct( - \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, + \Redis|Relay|\Relay\Cluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, private string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null, @@ -69,7 +69,7 @@ public function __construct( throw new InvalidArgumentException(\sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection()))); } - $isRelay = $redis instanceof Relay; + $isRelay = $redis instanceof Relay || $redis instanceof \Relay\Cluster; if ($isRelay || \defined('Redis::OPT_COMPRESSION') && \in_array($redis::class, [\Redis::class, \RedisArray::class, \RedisCluster::class], true)) { $compression = $redis->getOption($isRelay ? Relay::OPT_COMPRESSION : \Redis::OPT_COMPRESSION); @@ -225,7 +225,7 @@ protected function doInvalidate(array $tagIds): bool $results = $this->pipeline(function () use ($tagIds, $lua) { if ($this->redis instanceof \Predis\ClientInterface) { $prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : ''; - } elseif (\is_array($prefix = $this->redis->getOption($this->redis instanceof Relay ? Relay::OPT_PREFIX : \Redis::OPT_PREFIX) ?? '')) { + } elseif (\is_array($prefix = $this->redis->getOption(($this->redis instanceof Relay || $this->redis instanceof \Relay\Cluster) ? Relay::OPT_PREFIX : \Redis::OPT_PREFIX) ?? '')) { $prefix = current($prefix); } diff --git a/CHANGELOG.md b/CHANGELOG.md index 038915c4..b92cd754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.3 +--- + + * Add support for `\Relay\Cluster` in `RedisAdapter` + 7.2 --- diff --git a/Tests/Adapter/AbstractRedisAdapterTestCase.php b/Tests/Adapter/AbstractRedisAdapterTestCase.php index c83365cc..03a0f873 100644 --- a/Tests/Adapter/AbstractRedisAdapterTestCase.php +++ b/Tests/Adapter/AbstractRedisAdapterTestCase.php @@ -13,6 +13,7 @@ use Psr\Cache\CacheItemPoolInterface; use Relay\Relay; +use Relay\Cluster as RelayCluster; use Symfony\Component\Cache\Adapter\RedisAdapter; abstract class AbstractRedisAdapterTestCase extends AdapterTestCase @@ -23,7 +24,7 @@ abstract class AbstractRedisAdapterTestCase extends AdapterTestCase 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', ]; - protected static \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis; + protected static \Redis|Relay|RelayCluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis; public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface { diff --git a/Tests/Adapter/RedisTagAwareRelayClusterAdapterTest.php b/Tests/Adapter/RedisTagAwareRelayClusterAdapterTest.php new file mode 100644 index 00000000..4939d2df --- /dev/null +++ b/Tests/Adapter/RedisTagAwareRelayClusterAdapterTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter; +use Symfony\Component\Cache\Traits\RelayClusterProxy; + +/** + * @requires extension relay + * + * @group integration + */ +class RedisTagAwareRelayClusterAdapterTest extends RelayClusterAdapterTest +{ + use TagAwareTestTrait; + + protected function setUp(): void + { + parent::setUp(); + $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite'; + } + + public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface + { + $this->assertInstanceOf(RelayClusterProxy::class, self::$redis); + $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + + return $adapter; + } +} diff --git a/Tests/Adapter/RelayClusterAdapterTest.php b/Tests/Adapter/RelayClusterAdapterTest.php new file mode 100644 index 00000000..1f9718a6 --- /dev/null +++ b/Tests/Adapter/RelayClusterAdapterTest.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Relay\Relay; +use Relay\Cluster as RelayCluster; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Adapter\RedisAdapter; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\Traits\RelayClusterProxy; + +/** + * @requires extension relay + * + * @group integration + */ +class RelayClusterAdapterTest extends AbstractRedisAdapterTestCase +{ + public static function setUpBeforeClass(): void + { + if (!class_exists(RelayCluster::class)) { + self::markTestSkipped('The Relay\Cluster class is required.'); + } + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + + self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true, 'class' => RelayCluster::class]); + self::$redis->setOption(Relay::OPT_PREFIX, 'prefix_'); + } + + public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface + { + $this->assertInstanceOf(RelayClusterProxy::class, self::$redis); + $adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + + return $adapter; + } + + /** + * @dataProvider provideFailedCreateConnection + */ + public function testFailedCreateConnection(string $dsn) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Relay cluster connection failed:'); + RedisAdapter::createConnection($dsn); + } + + public static function provideFailedCreateConnection(): array + { + return [ + ['redis://localhost:1234?redis_cluster=1&class=Relay\Cluster'], + ['redis://foo@localhost?redis_cluster=1&class=Relay\Cluster'], + ['redis://localhost/123?redis_cluster=1&class=Relay\Cluster'], + ]; + } +} diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index 0be40602..47767a88 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -13,7 +13,9 @@ use PHPUnit\Framework\TestCase; use Relay\Relay; +use Relay\Cluster as RelayCluster; use Symfony\Component\Cache\Traits\RedisProxyTrait; +use Symfony\Component\Cache\Traits\RelayClusterProxy; use Symfony\Component\Cache\Traits\RelayProxy; use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Component\VarExporter\ProxyHelper; @@ -121,4 +123,52 @@ public function testRelayProxy() $this->assertEquals($expectedProxy, $proxy); } + + + /** + * @requires extension relay + */ + public function testRelayClusterProxy() + { + $proxy = file_get_contents(\dirname(__DIR__, 2).'/Traits/RelayClusterProxy.php'); + $proxy = substr($proxy, 0, 2 + strpos($proxy, '}')); + $expectedProxy = $proxy; + $methods = []; + $expectedMethods = []; + + foreach ((new \ReflectionClass(RelayClusterProxy::class))->getMethods() as $method) { + if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + continue; + } + + $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; + $expectedMethods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<initializeLazyObject()->{$method->name}({$args}); + } + + EOPHP; + } + + foreach ((new \ReflectionClass(RelayCluster::class))->getMethods() as $method) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { + continue; + } + $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; + $methods[$method->name] = "\n ".ProxyHelper::exportSignature($method, false, $args)."\n".<<initializeLazyObject()->{$method->name}({$args}); + } + + EOPHP; + } + + uksort($methods, 'strnatcmp'); + $proxy .= implode('', $methods)."}\n"; + + uksort($expectedMethods, 'strnatcmp'); + $expectedProxy .= implode('', $expectedMethods)."}\n"; + + $this->assertEquals($expectedProxy, $proxy); + } } diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index f6bb9bbe..480e4f77 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -21,6 +21,7 @@ use Predis\Response\ErrorInterface; use Predis\Response\Status; use Relay\Relay; +use Relay\Cluster as RelayCluster; use Relay\Sentinel; use Symfony\Component\Cache\Exception\CacheException; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -41,19 +42,21 @@ trait RedisTrait 'persistent_id' => null, 'timeout' => 30, 'read_timeout' => 0, + 'command_timeout' => 0, 'retry_interval' => 0, 'tcp_keepalive' => 0, 'lazy' => null, 'redis_cluster' => false, + 'relay_cluster_context' => [], 'redis_sentinel' => null, 'dbindex' => 0, 'failover' => 'none', 'ssl' => null, // see https://php.net/context.ssl ]; - private \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis; + private \Redis|Relay|RelayCluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis; private MarshallerInterface $marshaller; - private function init(\Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller): void + private function init(\Redis|Relay|RelayCluster|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, string $namespace, int $defaultLifetime, ?MarshallerInterface $marshaller): void { parent::__construct($namespace, $defaultLifetime); @@ -85,7 +88,7 @@ private function init(\Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInter * * @throws InvalidArgumentException when the DSN is invalid */ - public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|Relay + public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|Relay|RelayCluster { if (str_starts_with($dsn, 'redis:')) { $scheme = 'redis'; @@ -187,14 +190,18 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra if (isset($params['lazy'])) { $params['lazy'] = filter_var($params['lazy'], \FILTER_VALIDATE_BOOLEAN); } - $params['redis_cluster'] = filter_var($params['redis_cluster'], \FILTER_VALIDATE_BOOLEAN); + $params['redis_cluster'] = filter_var($params['redis_cluster'], \FILTER_VALIDATE_BOOLEAN); if ($params['redis_cluster'] && isset($params['redis_sentinel'])) { throw new InvalidArgumentException('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.'); } $class = $params['class'] ?? match (true) { - $params['redis_cluster'] => \extension_loaded('redis') ? \RedisCluster::class : \Predis\Client::class, + $params['redis_cluster'] => match (true) { + \extension_loaded('redis') => \RedisCluster::class, + \extension_loaded('relay') => RelayCluster::class, + default => \Predis\Client::class, + }, isset($params['redis_sentinel']) => match (true) { \extension_loaded('redis') => \Redis::class, \extension_loaded('relay') => Relay::class, @@ -348,6 +355,66 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra if (0 < $params['tcp_keepalive'] && (!$isRedisExt || \defined('Redis::OPT_TCP_KEEPALIVE'))) { $redis->setOption($isRedisExt ? \Redis::OPT_TCP_KEEPALIVE : Relay::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']); } + } elseif (is_a($class, RelayCluster::class, true)) { + if (version_compare(phpversion('relay'), '0.10.0', '<')) { + throw new InvalidArgumentException('Using RelayCluster is supported from ext-relay 0.10.0 or higher.'); + } + + $initializer = static function () use ($class, $params, $hosts) { + foreach ($hosts as $i => $host) { + $hosts[$i] = match ($host['scheme']) { + 'tcp' => $host['host'].':'.$host['port'], + 'tls' => 'tls://'.$host['host'].':'.$host['port'], + default => $host['path'], + }; + } + + try { + $relayClusterContext = $params['relay_cluster_context']; + + foreach (['allow_self_signed', 'verify_peer_name','verify_peer'] as $contextStreamBoolField) { + if(isset($relayClusterContext['stream'][$contextStreamBoolField])) { + $relayClusterContext['stream'][$contextStreamBoolField] = filter_var($relayClusterContext['stream'][$contextStreamBoolField], \FILTER_VALIDATE_BOOL); + } + } + + foreach (['use-cache', 'client-tracking','throw-on-error','client-invalidations','reply-literal','persistent'] as $contextBoolField) { + if(isset($relayClusterContext[$contextBoolField])) { + $relayClusterContext[$contextBoolField] = filter_var($relayClusterContext[$contextBoolField], \FILTER_VALIDATE_BOOL); + } + } + + foreach (['max-retries', 'serializer','compression','compression-level'] as $contextIntField) { + if(isset($relayClusterContext[$contextIntField])) { + $relayClusterContext[$contextIntField] = filter_var($relayClusterContext[$contextIntField], \FILTER_VALIDATE_INT); + } + } + + $relayCluster = new $class( + name: null, + seeds: $hosts, + connect_timeout: $params['timeout'], + command_timeout: $params['command_timeout'], + persistent: (bool) $params['persistent'], + auth: $params['auth'] ?? null, + context: $relayClusterContext + ); + } catch (\Relay\Exception $e) { + throw new InvalidArgumentException('Relay cluster connection failed: '.$e->getMessage()); + } + + if (0 < $params['tcp_keepalive']) { + $relayCluster->setOption(Relay::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']); + } + + if (0 < $params['read_timeout']) { + $relayCluster->setOption(Relay::OPT_READ_TIMEOUT, $params['read_timeout']); + } + + return $relayCluster; + }; + + $redis = $params['lazy'] ? RelayClusterProxy::createLazyProxy($initializer) : $initializer(); } elseif (is_a($class, \RedisCluster::class, true)) { $initializer = static function () use ($isRedisExt, $class, $params, $hosts) { foreach ($hosts as $i => $host) { @@ -478,6 +545,35 @@ protected function doClear(string $namespace): bool } $cleared = true; + + if ($this->redis instanceof RelayCluster) { + $prefix = Relay::SCAN_PREFIX & $this->redis->getOption(Relay::OPT_SCAN) ? '' : $this->redis->getOption(Relay::OPT_PREFIX); + $prefixLen = \strlen($prefix); + $pattern = $prefix.$namespace.'*'; + foreach ($this->redis->_masters() as $ipAndPort) { + $address = implode(':', $ipAndPort); + $cursor = null; + do { + $keys = $this->redis->scan($cursor, $address, $pattern, 1000); + if (isset($keys[1]) && \is_array($keys[1])) { + $cursor = $keys[0]; + $keys = $keys[1]; + } + + if ($keys) { + if ($prefixLen) { + foreach ($keys as $i => $key) { + $keys[$i] = substr($key, $prefixLen); + } + } + $this->doDelete($keys); + } + } while ($cursor); + } + + return $cleared; + } + $hosts = $this->getHosts(); $host = reset($hosts); if ($host instanceof \Predis\Client) { @@ -605,8 +701,9 @@ private function pipeline(\Closure $generator, ?object $redis = null): \Generato $ids = []; $redis ??= $this->redis; - if ($redis instanceof \RedisCluster || ($redis instanceof \Predis\ClientInterface && ($redis->getConnection() instanceof RedisCluster || $redis->getConnection() instanceof Predis2RedisCluster))) { + if ($redis instanceof \RedisCluster || $redis instanceof \Relay\Cluster || ($redis instanceof \Predis\ClientInterface && ($redis->getConnection() instanceof RedisCluster || $redis->getConnection() instanceof Predis2RedisCluster))) { // phpredis & predis don't support pipelining with RedisCluster + // \Relay\Cluster does not support multi with pipeline mode // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining // see https://github.com/nrk/predis/issues/267#issuecomment-123781423 $results = []; diff --git a/Traits/RelayClusterProxy.php b/Traits/RelayClusterProxy.php new file mode 100644 index 00000000..92466e56 --- /dev/null +++ b/Traits/RelayClusterProxy.php @@ -0,0 +1,1203 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Relay\Cluster; +use Relay\Relay; +use Symfony\Component\VarExporter\LazyObjectInterface; +use Symfony\Contracts\Service\ResetInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class); +class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class); +class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); + +/** + * @internal + */ +class RelayClusterProxy extends \Relay\Cluster implements ResetInterface, LazyObjectInterface +{ + use RedisProxyTrait { + resetLazyObject as reset; + } + + public function __construct( + string|null $name, + array|null $seeds = null, + int|float $connect_timeout = 0, + int|float $command_timeout = 0, + bool $persistent = false, + #[\SensitiveParameter] mixed $auth = null, + array|null $context = null + ) { + $this->initializeLazyObject()->__construct(...\func_get_args()); + } + + public function close(): bool + { + return $this->initializeLazyObject()->close(...\func_get_args()); + } + + public function listen(?callable $callback): bool + { + return $this->initializeLazyObject()->listen(...\func_get_args()); + } + + public function onFlushed(?callable $callback): bool + { + return $this->initializeLazyObject()->onFlushed(...\func_get_args()); + } + + public function onInvalidated(?callable $callback, ?string $pattern = null): bool + { + return $this->initializeLazyObject()->onInvalidated(...\func_get_args()); + } + + public function dispatchEvents(): false|int + { + return $this->initializeLazyObject()->dispatchEvents(...\func_get_args()); + } + + public function dump(mixed $key): \Relay\Cluster|string|false + { + return $this->initializeLazyObject()->dump(...\func_get_args()); + } + + public function getOption(int $option): mixed + { + return $this->initializeLazyObject()->getOption(...\func_get_args()); + } + + public function setOption(int $option, mixed $value): bool + { + return $this->initializeLazyObject()->setOption(...\func_get_args()); + } + + public function getTransferredBytes(): array|false + { + return $this->initializeLazyObject()->getTransferredBytes(...\func_get_args()); + } + + public function getrange(mixed $key, int $start, int $end): \Relay\Cluster|string|false + { + return $this->initializeLazyObject()->getrange(...\func_get_args()); + } + + public function addIgnorePatterns(string ...$pattern): int + { + return $this->initializeLazyObject()->addIgnorePatterns(...\func_get_args()); + } + + public function addAllowPatterns(string ...$pattern): int + { + return $this->initializeLazyObject()->addAllowPatterns(...\func_get_args()); + } + + public function _serialize(mixed $value): string + { + return $this->initializeLazyObject()->_serialize(...\func_get_args()); + } + + public function _unserialize(string $value): mixed + { + return $this->initializeLazyObject()->_unserialize(...\func_get_args()); + } + + public function _compress(string $value): string + { + return $this->initializeLazyObject()->_compress(...\func_get_args()); + } + + public function _uncompress(string $value): string + { + return $this->initializeLazyObject()->_uncompress(...\func_get_args()); + } + + public function _pack(mixed $value): string + { + return $this->initializeLazyObject()->_pack(...\func_get_args()); + } + + public function _unpack(string $value): mixed + { + return $this->initializeLazyObject()->_unpack(...\func_get_args()); + } + + public function _prefix(mixed $value): string + { + return $this->initializeLazyObject()->_prefix(...\func_get_args()); + } + + public function getLastError(): ?string + { + return $this->initializeLazyObject()->getLastError(...\func_get_args()); + } + + public function clearLastError(): bool + { + return $this->initializeLazyObject()->clearLastError(...\func_get_args()); + } + + public function clearTransferredBytes(): bool + { + return $this->initializeLazyObject()->clearTransferredBytes(...\func_get_args()); + } + + public function endpointId(): array|false + { + return $this->initializeLazyObject()->endpointId(...\func_get_args()); + } + + + public function rawCommand(array|string $key_or_address, string $cmd, mixed ...$args): mixed + { + return $this->initializeLazyObject()->rawCommand(...\func_get_args()); + } + + public function cluster(array|string $key_or_address, string $operation, mixed ...$args): mixed + { + return $this->initializeLazyObject()->cluster(...\func_get_args()); + } + + public function info(array|string $key_or_address, string ...$sections): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->info(...\func_get_args()); + } + + public function flushdb(array|string $key_or_address, bool|null $sync = null): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->flushdb(...\func_get_args()); + } + + public function flushall(array|string $key_or_address, bool|null $sync = null): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->flushall(...\func_get_args()); + } + + public function dbsize(array|string $key_or_address): \Relay\Cluster|int|false + { + return $this->initializeLazyObject()->dbsize(...\func_get_args()); + } + + public function waitaof(array|string $key_or_address, int $numlocal, int $numremote, int $timeout): \Relay\Relay|array|false + { + return $this->initializeLazyObject()->waitaof(...\func_get_args()); + } + + public function restore(mixed $key, int $ttl, string $value, array|null $options = null): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->restore(...\func_get_args()); + } + + public function echo(array|string $key_or_address, string $message): \Relay\Cluster|string|false + { + return $this->initializeLazyObject()->echo(...\func_get_args()); + } + + public function ping(array|string $key_or_address, string|null $message = null): \Relay\Cluster|bool|string + { + return $this->initializeLazyObject()->ping(...\func_get_args()); + } + + public function idleTime(): int + { + return $this->initializeLazyObject()->idleTime(...\func_get_args()); + } + + public function randomkey(array|string $key_or_address): \Relay\Cluster|bool|string + { + return $this->initializeLazyObject()->randomkey(...\func_get_args()); + } + + public function time(array|string $key_or_address): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->time(...\func_get_args()); + } + + public function bgrewriteaof(array|string $key_or_address): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); + } + + public function lastsave(array|string $key_or_address): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->lastsave(...\func_get_args()); + } + + public function lcs(mixed $key1, mixed $key2, array|null $options = null): mixed + { + return $this->initializeLazyObject()->lcs(...\func_get_args()); + } + + public function bgsave(array|string $key_or_address, bool $schedule = false): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->bgsave(...\func_get_args()); + } + + public function save(array|string $key_or_address): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->save(...\func_get_args()); + } + + public function role(array|string $key_or_address): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->role(...\func_get_args()); + } + + public function ttl(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->ttl(...\func_get_args()); + } + + public function pttl(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->pttl(...\func_get_args()); + } + + public function exists(mixed ...$keys): \Relay\Cluster|bool|int + { + return $this->initializeLazyObject()->exists(...\func_get_args()); + } + + public function eval(mixed $script, array $args = [], int $num_keys = 0): mixed + { + return $this->initializeLazyObject()->eval(...\func_get_args()); + } + + public function eval_ro(mixed $script, array $args = [], int $num_keys = 0): mixed + { + return $this->initializeLazyObject()->eval_ro(...\func_get_args()); + } + + public function evalsha(string $sha, array $args = [], int $num_keys = 0): mixed + { + return $this->initializeLazyObject()->evalsha(...\func_get_args()); + } + + public function evalsha_ro(string $sha, array $args = [], int $num_keys = 0): mixed + { + return $this->initializeLazyObject()->evalsha_ro(...\func_get_args()); + } + + public function client(array|string $key_or_address, string $operation, mixed ...$args): mixed + { + return $this->initializeLazyObject()->client(...\func_get_args()); + } + + public function geoadd(mixed $key, float $lng, float $lat, string $member, mixed ...$other_triples_and_options): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->geoadd(...\func_get_args()); + } + + public function geodist(mixed $key, string $src, string $dst, string|null $unit = null): \Relay\Cluster|float|false + { + return $this->initializeLazyObject()->geodist(...\func_get_args()); + } + + public function geohash(mixed $key, string $member, string ...$other_members): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->geohash(...\func_get_args()); + } + + public function georadius(mixed $key, float $lng, float $lat, float $radius, string $unit, array $options = []): mixed + { + return $this->initializeLazyObject()->georadius(...\func_get_args()); + } + + public function georadiusbymember(mixed $key, string $member, float $radius, string $unit, array $options = []): mixed + { + return $this->initializeLazyObject()->georadiusbymember(...\func_get_args()); + } + + public function georadiusbymember_ro(mixed $key, string $member, float $radius, string $unit, array $options = []): mixed + { + return $this->initializeLazyObject()->georadiusbymember_ro(...\func_get_args()); + } + + public function georadius_ro(mixed $key, float $lng, float $lat, float $radius, string $unit, array $options = []): mixed + { + return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); + } + + public function geosearchstore(mixed $dstkey, mixed $srckey, array|string $position, array|int|float $shape, string $unit, array $options = []): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->geosearchstore(...\func_get_args()); + } + + public function geosearch(mixed $key, array|string $position, array|int|float $shape, string $unit, array $options = []): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->geosearch(...\func_get_args()); + } + + public function get(mixed $key): mixed + { + return $this->initializeLazyObject()->get(...\func_get_args()); + } + + public function getset(mixed $key, mixed $value): mixed + { + return $this->initializeLazyObject()->getset(...\func_get_args()); + } + + public function setrange(mixed $key, int $start, mixed $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->setrange(...\func_get_args()); + } + + public function getbit(mixed $key, int $pos): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->getbit(...\func_get_args()); + } + + public function bitcount(mixed $key, int $start = 0, int $end = -1, bool $by_bit = false): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->bitcount(...\func_get_args()); + } + + public function config(array|string $key_or_address, string $operation, mixed ...$args): mixed + { + return $this->initializeLazyObject()->config(...\func_get_args()); + } + + public function command(mixed ...$args): \Relay\Cluster|array|false|int + { + return $this->initializeLazyObject()->command(...\func_get_args()); + } + + public function bitop(string $operation, string $dstkey, string $srckey, string ...$other_keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->bitop(...\func_get_args()); + } + + public function bitpos(mixed $key, int $bit, ?int $start = null, ?int $end = null, bool $by_bit = false): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->bitpos(...\func_get_args()); + } + + public function blmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos, float $timeout): \Relay\Cluster|string|null|false + { + return $this->initializeLazyObject()->blmove(...\func_get_args()); + } + + public function lmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos): Cluster|string|null|false { + return $this->initializeLazyObject()->lmove(...\func_get_args()); + } + + public function setbit(mixed $key, int $pos, int $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->setbit(...\func_get_args()); + } + + public function acl(array|string $key_or_address, string $operation, string ...$args): mixed + { + return $this->initializeLazyObject()->acl(...\func_get_args()); + } + + public function append(mixed $key, mixed $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->append(...\func_get_args()); + } + + public function set(mixed $key, mixed $value, mixed $options = null): \Relay\Cluster|string|bool + { + return $this->initializeLazyObject()->set(...\func_get_args()); + } + + public function getex(mixed $key, ?array $options = null): mixed + { + return $this->initializeLazyObject()->getex(...\func_get_args()); + } + + public function setex(mixed $key, int $seconds, mixed $value): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->setex(...\func_get_args()); + } + + public function pfadd(mixed $key, array $elements): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->pfadd(...\func_get_args()); + } + + public function pfcount(mixed $key): \Relay\Cluster|int|false + { + return $this->initializeLazyObject()->pfcount(...\func_get_args()); + } + + public function pfmerge(string $dstkey, array $srckeys): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->pfmerge(...\func_get_args()); + } + + public function psetex(mixed $key, int $milliseconds, mixed $value): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->psetex(...\func_get_args()); + } + + public function publish(string $channel, string $message): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->publish(...\func_get_args()); + } + + public function pubsub(array|string $key_or_address, string $operation, mixed ...$args): mixed + { + return $this->initializeLazyObject()->pubsub(...\func_get_args()); + } + + public function setnx(mixed $key, mixed $value): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->setnx(...\func_get_args()); + } + + public function mget(array $keys): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->mget(...\func_get_args()); + } + + public function mset(array $kvals): \Relay\Cluster|array|bool + { + return $this->initializeLazyObject()->mset(...\func_get_args()); + } + + public function msetnx(array $kvals): \Relay\Cluster|array|bool + { + return $this->initializeLazyObject()->msetnx(...\func_get_args()); + } + + public function rename(mixed $key, mixed $newkey): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->rename(...\func_get_args()); + } + + public function renamenx(mixed $key, mixed $newkey): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->renamenx(...\func_get_args()); + } + + public function del(mixed ...$keys): \Relay\Cluster|bool|int + { + return $this->initializeLazyObject()->del(...\func_get_args()); + } + + public function unlink(mixed ...$keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->unlink(...\func_get_args()); + } + + public function expire(mixed $key, int $seconds, string|null $mode = null): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->expire(...\func_get_args()); + } + + public function pexpire(mixed $key, int $milliseconds): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->pexpire(...\func_get_args()); + } + + public function expireat(mixed $key, int $timestamp): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->expireat(...\func_get_args()); + } + + public function expiretime(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->expiretime(...\func_get_args()); + } + + public function pexpireat(mixed $key, int $timestamp_ms): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->pexpireat(...\func_get_args()); + } + + public static function flushMemory(?string $endpointId = null, ?int $db = null): bool + { + return \Relay\Cluster::flushMemory(...\func_get_args()); + } + + public function pexpiretime(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->pexpiretime(...\func_get_args()); + } + + public function persist(mixed $key): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->persist(...\func_get_args()); + } + + public function type(mixed $key): \Relay\Cluster|bool|int|string + { + return $this->initializeLazyObject()->type(...\func_get_args()); + } + + public function lrange(mixed $key, int $start, int $stop): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->lrange(...\func_get_args()); + } + + public function lpush(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->lpush(...\func_get_args()); + } + + public function rpush(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->rpush(...\func_get_args()); + } + + public function lpushx(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->lpushx(...\func_get_args()); + } + + public function rpushx(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->rpushx(...\func_get_args()); + } + + public function lset(mixed $key, int $index, mixed $member): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->lset(...\func_get_args()); + } + + public function lpop(mixed $key, int $count = 1): mixed + { + return $this->initializeLazyObject()->lpop(...\func_get_args()); + } + + public function lpos(mixed $key, mixed $value, array|null $options = null): mixed + { + return $this->initializeLazyObject()->lpos(...\func_get_args()); + } + + public function rpop(mixed $key, int $count = 1): mixed + { + return $this->initializeLazyObject()->rpop(...\func_get_args()); + } + + public function rpoplpush(mixed $srckey, mixed $dstkey): mixed + { + return $this->initializeLazyObject()->rpoplpush(...\func_get_args()); + } + + public function brpoplpush(mixed $srckey, mixed $dstkey, float $timeout): mixed + { + return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); + } + + public function blpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->blpop(...\func_get_args()); + } + + public function blmpop(float $timeout, array $keys, string $from, int $count = 1): mixed + { + return $this->initializeLazyObject()->blmpop(...\func_get_args()); + } + + public function bzmpop(float $timeout, array $keys, string $from, int $count = 1): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->bzmpop(...\func_get_args()); + } + + public function lmpop(array $keys, string $from, int $count = 1): mixed + { + return $this->initializeLazyObject()->lmpop(...\func_get_args()); + } + + public function zmpop(array $keys, string $from, int $count = 1): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->zmpop(...\func_get_args()); + } + + public function brpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->brpop(...\func_get_args()); + } + + public function bzpopmax(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->bzpopmax(...\func_get_args()); + } + + public function bzpopmin(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + { + return $this->initializeLazyObject()->bzpopmin(...\func_get_args()); + } + + public function object(string $op, mixed $key): mixed + { + return $this->initializeLazyObject()->object(...\func_get_args()); + } + + public function geopos(mixed $key, mixed ...$members): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->geopos(...\func_get_args()); + } + + public function lrem(mixed $key, mixed $member, int $count = 0): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->lrem(...\func_get_args()); + } + + public function lindex(mixed $key, int $index): mixed + { + return $this->initializeLazyObject()->lindex(...\func_get_args()); + } + + public function linsert(mixed $key, string $op, mixed $pivot, mixed $element): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->linsert(...\func_get_args()); + } + + public function ltrim(mixed $key, int $start, int $end): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->ltrim(...\func_get_args()); + } + + public static function maxMemory(): int { + return \Relay\Cluster::maxMemory(); + } + + public function hget(mixed $key, mixed $member): mixed + { + return $this->initializeLazyObject()->hget(...\func_get_args()); + } + + public function hstrlen(mixed $key, mixed $member): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->hstrlen(...\func_get_args()); + } + + public function hgetall(mixed $key): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->hgetall(...\func_get_args()); + } + + public function hkeys(mixed $key): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->hkeys(...\func_get_args()); + } + + public function hvals(mixed $key): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->hvals(...\func_get_args()); + } + + public function hmget(mixed $key, array $members): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->hmget(...\func_get_args()); + } + + public function hmset(mixed $key, array $members): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->hmset(...\func_get_args()); + } + + public function hexists(mixed $key, mixed $member): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->hexists(...\func_get_args()); + } + + public function hrandfield(mixed $key, array|null $options = null): \Relay\Cluster|array|string|false + { + return $this->initializeLazyObject()->hrandfield(...\func_get_args()); + } + + public function hsetnx(mixed $key, mixed $member, mixed $value): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->hsetnx(...\func_get_args()); + } + + public function hset(mixed $key, mixed ...$keys_and_vals): \Relay\Cluster|int|false + { + return $this->initializeLazyObject()->hset(...\func_get_args()); + } + + public function hdel(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->hdel(...\func_get_args()); + } + + public function hincrby(mixed $key, mixed $member, int $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->hincrby(...\func_get_args()); + } + + public function hincrbyfloat(mixed $key, mixed $member, float $value): \Relay\Cluster|bool|float + { + return $this->initializeLazyObject()->hincrbyfloat(...\func_get_args()); + } + + public function incr(mixed $key, int $by = 1): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->incr(...\func_get_args()); + } + + public function decr(mixed $key, int $by = 1): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->decr(...\func_get_args()); + } + + public function incrby(mixed $key, int $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->incrby(...\func_get_args()); + } + + public function decrby(mixed $key, int $value): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->decrby(...\func_get_args()); + } + + public function incrbyfloat(mixed $key, float $value): \Relay\Cluster|false|float + { + return $this->initializeLazyObject()->incrbyfloat(...\func_get_args()); + } + + public function sdiff(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->sdiff(...\func_get_args()); + } + + public function sdiffstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->sdiffstore(...\func_get_args()); + } + + public function sinter(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->sinter(...\func_get_args()); + } + + public function sintercard(array $keys, int $limit = -1): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->sintercard(...\func_get_args()); + } + + public function sinterstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->sinterstore(...\func_get_args()); + } + + public function sunion(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->sunion(...\func_get_args()); + } + + public function sunionstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->sunionstore(...\func_get_args()); + } + + public function subscribe(array $channels, callable $callback): bool + { + return $this->initializeLazyObject()->subscribe(...\func_get_args()); + } + + public function unsubscribe(array $channels = []): bool + { + return $this->initializeLazyObject()->unsubscribe(...\func_get_args()); + } + + public function psubscribe(array $patterns, callable $callback): bool + { + return $this->initializeLazyObject()->psubscribe(...\func_get_args()); + } + + public function punsubscribe(array $patterns = []): bool + { + return $this->initializeLazyObject()->punsubscribe(...\func_get_args()); + } + + public function ssubscribe(array $channels, callable $callback): bool + { + return $this->initializeLazyObject()->ssubscribe(...\func_get_args()); + } + + public function sunsubscribe(array $channels = []): bool + { + return $this->initializeLazyObject()->sunsubscribe(...\func_get_args()); + } + + public function touch(array|string $key_or_array, mixed ...$more_keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->touch(...\func_get_args()); + } + + public function multi(int $mode = Relay::MULTI): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->multi(...\func_get_args()); + } + + public function exec(): array|false + { + return $this->initializeLazyObject()->exec(...\func_get_args()); + } + + public function watch(mixed $key, mixed ...$other_keys): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->watch(...\func_get_args()); + } + + public function unwatch(): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->unwatch(...\func_get_args()); + } + + public function discard(): bool + { + return $this->initializeLazyObject()->discard(...\func_get_args()); + } + + public function getMode(bool $masked = false): int + { + return $this->initializeLazyObject()->getMode(...\func_get_args()); + } + + public function scan(mixed &$iterator, array|string $key_or_address, mixed $match = null, int $count = 0, string|null $type = null): array|false + { + return $this->initializeLazyObject()->scan($iterator, ...\array_slice(\func_get_args(), 1)); + } + + public function hscan(mixed $key, mixed &$iterator, mixed $match = null, int $count = 0): array|false + { + return $this->initializeLazyObject()->hscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + } + + public function sscan(mixed $key, mixed &$iterator, mixed $match = null, int $count = 0): array|false + { + return $this->initializeLazyObject()->sscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + } + + public function zscan(mixed $key, mixed &$iterator, mixed $match = null, int $count = 0): array|false + { + return $this->initializeLazyObject()->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); + } + + public function zscore(mixed $key, mixed $member): \Relay\Cluster|float|false + { + return $this->initializeLazyObject()->zscore(...\func_get_args()); + } + + public function keys(mixed $pattern): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->keys(...\func_get_args()); + } + + public function slowlog(array|string $key_or_address, string $operation, mixed ...$args): \Relay\Cluster|array|bool|int + { + return $this->initializeLazyObject()->slowlog(...\func_get_args()); + } + + public function xadd(mixed $key, string $id, array $values, int $maxlen = 0, bool $approx = false, bool $nomkstream = false): Cluster|string|false + { + return $this->initializeLazyObject()->xadd(...\func_get_args()); + } + + public function smembers(mixed $key): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->smembers(...\func_get_args()); + } + + public function sismember(mixed $key, mixed $member): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->sismember(...\func_get_args()); + } + + public function smismember(mixed $key, mixed ...$members): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->smismember(...\func_get_args()); + } + + public function srem(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->srem(...\func_get_args()); + } + + public function sadd(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->sadd(...\func_get_args()); + } + + public function sort(mixed $key, array $options = []): \Relay\Cluster|array|false|int + { + return $this->initializeLazyObject()->sort(...\func_get_args()); + } + + public function sort_ro(mixed $key, array $options = []): \Relay\Cluster|array|false|int + { + return $this->initializeLazyObject()->sort_ro(...\func_get_args()); + } + + public function smove(mixed $srckey, mixed $dstkey, mixed $member): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->smove(...\func_get_args()); + } + + public function spop(mixed $key, int $count = 1): mixed + { + return $this->initializeLazyObject()->spop(...\func_get_args()); + } + + public function srandmember(mixed $key, int $count = 1): mixed + { + return $this->initializeLazyObject()->srandmember(...\func_get_args()); + } + + public function scard(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->scard(...\func_get_args()); + } + + public function script(array|string $key_or_address, string $operation, string ...$args): mixed + { + return $this->initializeLazyObject()->script(...\func_get_args()); + } + + public function strlen(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->strlen(...\func_get_args()); + } + + public function hlen(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->hlen(...\func_get_args()); + } + + public function llen(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->llen(...\func_get_args()); + } + + public function xack(mixed $key, string $group, array $ids): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->xack(...\func_get_args()); + } + + public function xclaim(mixed $key, string $group, string $consumer, int $min_idle, array $ids, array $options): \Relay\Cluster|array|bool + { + return $this->initializeLazyObject()->xclaim(...\func_get_args()); + } + + public function xautoclaim(mixed $key, string $group, string $consumer, int $min_idle, string $start, int $count = -1, bool $justid = false): \Relay\Cluster|array|bool + { + return $this->initializeLazyObject()->xautoclaim(...\func_get_args()); + } + + public function xlen(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->xlen(...\func_get_args()); + } + + public function xgroup(string $operation, mixed $key = null, ?string $group = null, ?string $id_or_consumer = null, bool $mkstream = false, int $entries_read = -2): mixed + { + return $this->initializeLazyObject()->xgroup(...\func_get_args()); + } + + public function xdel(mixed $key, array $ids): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->xdel(...\func_get_args()); + } + + public function xinfo(string $operation, string|null $arg1 = null, string|null $arg2 = null, int $count = -1): mixed + { + return $this->initializeLazyObject()->xinfo(...\func_get_args()); + } + + public function xpending(mixed $key, string $group, string|null $start = null, string|null $end = null, int $count = -1, string|null $consumer = null, int $idle = 0): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->xpending(...\func_get_args()); + } + + public function xrange(mixed $key, string $start, string $end, int $count = -1): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->xrange(...\func_get_args()); + } + + public function xread(array $streams, int $count = -1, int $block = -1): \Relay\Cluster|array|bool|null + { + return $this->initializeLazyObject()->xread(...\func_get_args()); + } + + public function xreadgroup(mixed $key, string $consumer, array $streams, int $count = 1, int $block = 1): \Relay\Cluster|array|bool|null + { + return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); + } + + public function xrevrange(mixed $key, string $end, string $start, int $count = -1): \Relay\Cluster|array|bool + { + return $this->initializeLazyObject()->xrevrange(...\func_get_args()); + } + + public function xtrim(mixed $key, string $threshold, bool $approx = false, bool $minid = false, int $limit = -1): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->xtrim(...\func_get_args()); + } + + public function zadd(mixed $key, mixed ...$args): mixed + { + return $this->initializeLazyObject()->zadd(...\func_get_args()); + } + + public function zrandmember(mixed $key, array|null $options = null): mixed + { + return $this->initializeLazyObject()->zrandmember(...\func_get_args()); + } + + public function zrange(mixed $key, string $start, string $end, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrange(...\func_get_args()); + } + + public function zrevrange(mixed $key, int $start, int $end, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrevrange(...\func_get_args()); + } + + public function zrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrangebyscore(...\func_get_args()); + } + + public function zrevrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrevrangebyscore(...\func_get_args()); + } + + public function zrevrank(mixed $key, mixed $rank, bool $withscore = false): Cluster|array|int|false + { + return $this->initializeLazyObject()->zrevrank(...\func_get_args()); + } + + public function zrangestore(mixed $dstkey, mixed $srckey, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zrangestore(...\func_get_args()); + } + + public function zrank(mixed $key, mixed $rank, bool $withscore = false): Cluster|array|int|false + { + return $this->initializeLazyObject()->zrank(...\func_get_args()); + } + + public function zrangebylex(mixed $key, mixed $min, mixed $max, int $offset = -1, int $count = -1): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrangebylex(...\func_get_args()); + } + + public function zrevrangebylex(mixed $key, mixed $max, mixed $min, int $offset = -1, int $count = -1): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zrevrangebylex(...\func_get_args()); + } + + public function zrem(mixed $key, mixed ...$args): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zrem(...\func_get_args()); + } + + public function zremrangebylex(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zremrangebylex(...\func_get_args()); + } + + public function zremrangebyrank(mixed $key, int $start, int $end): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zremrangebyrank(...\func_get_args()); + } + + public function zremrangebyscore(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zremrangebyscore(...\func_get_args()); + } + + public function zcard(mixed $key): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zcard(...\func_get_args()); + } + + public function zcount(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zcount(...\func_get_args()); + } + + public function zdiff(array $keys, array|null $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zdiff(...\func_get_args()); + } + + public function zdiffstore(mixed $dstkey, array $keys): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zdiffstore(...\func_get_args()); + } + + public function zincrby(mixed $key, float $score, mixed $member): \Relay\Cluster|false|float + { + return $this->initializeLazyObject()->zincrby(...\func_get_args()); + } + + public function zlexcount(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zlexcount(...\func_get_args()); + } + + public function zmscore(mixed $key, mixed ...$members): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zmscore(...\func_get_args()); + } + + public function zinter(array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zinter(...\func_get_args()); + } + + public function zintercard(array $keys, int $limit = -1): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zintercard(...\func_get_args()); + } + + public function zinterstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zinterstore(...\func_get_args()); + } + + public function zunion(array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zunion(...\func_get_args()); + } + + public function zunionstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|false|int + { + return $this->initializeLazyObject()->zunionstore(...\func_get_args()); + } + + public function zpopmin(mixed $key, int $count = 1): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zpopmin(...\func_get_args()); + } + + public function zpopmax(mixed $key, int $count = 1): \Relay\Cluster|array|false + { + return $this->initializeLazyObject()->zpopmax(...\func_get_args()); + } + + public function _getKeys(): array|false + { + return $this->initializeLazyObject()->_getKeys(...\func_get_args()); + } + + public function _masters(): array + { + return $this->initializeLazyObject()->_masters(...\func_get_args()); + } + + public function copy(mixed $srckey, mixed $dstkey, array|null $options = null): \Relay\Cluster|bool + { + return $this->initializeLazyObject()->copy(...\func_get_args()); + } +} From 32c7382d54c95b5cb8d575a009fb5164c726c742 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Feb 2025 18:04:06 +0100 Subject: [PATCH 29/44] Add support for `valkey:` / `valkeys:` schemes --- Adapter/AbstractAdapter.php | 4 +- CHANGELOG.md | 2 + Tests/Adapter/RedisAdapterSentinelTest.php | 8 +-- Traits/RedisTrait.php | 75 +++++++++++++--------- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/Adapter/AbstractAdapter.php b/Adapter/AbstractAdapter.php index c03868da..8cd2218d 100644 --- a/Adapter/AbstractAdapter.php +++ b/Adapter/AbstractAdapter.php @@ -111,7 +111,7 @@ public static function createSystemCache(string $namespace, int $defaultLifetime public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): mixed { - if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:')) { + if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:') || str_starts_with($dsn, 'valkey:') || str_starts_with($dsn, 'valkeys:')) { return RedisAdapter::createConnection($dsn, $options); } if (str_starts_with($dsn, 'memcached:')) { @@ -128,7 +128,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra return PdoAdapter::createConnection($dsn, $options); } - throw new InvalidArgumentException('Unsupported DSN: it does not start with "redis[s]:", "memcached:", "couchbase:", "mysql:", "oci:", "pgsql:", "sqlsrv:" nor "sqlite:".'); + throw new InvalidArgumentException('Unsupported DSN: it does not start with "redis[s]:", "valkey[s]:", "memcached:", "couchbase:", "mysql:", "oci:", "pgsql:", "sqlsrv:" nor "sqlite:".'); } public function commit(): bool diff --git a/CHANGELOG.md b/CHANGELOG.md index b92cd754..59195f03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ CHANGELOG --- * Add support for `\Relay\Cluster` in `RedisAdapter` + * Add support for `valkey:` / `valkeys:` schemes + * Rename options "redis_cluster" and "redis_sentinel" to "cluster" and "sentinel" respectively 7.2 --- diff --git a/Tests/Adapter/RedisAdapterSentinelTest.php b/Tests/Adapter/RedisAdapterSentinelTest.php index 6dc13b81..9103eec5 100644 --- a/Tests/Adapter/RedisAdapterSentinelTest.php +++ b/Tests/Adapter/RedisAdapterSentinelTest.php @@ -32,15 +32,15 @@ public static function setUpBeforeClass(): void self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.'); } - self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']&timeout=0&retry_interval=0&read_timeout=0', ['redis_sentinel' => $service, 'prefix' => 'prefix_']); + self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']&timeout=0&retry_interval=0&read_timeout=0', ['sentinel' => $service, 'prefix' => 'prefix_']); } public function testInvalidDSNHasBothClusterAndSentinel() { - $dsn = 'redis:?host[redis1]&host[redis2]&host[redis3]&redis_cluster=1&redis_sentinel=mymaster'; + $dsn = 'redis:?host[redis1]&host[redis2]&host[redis3]&cluster=1&sentinel=mymaster'; $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.'); + $this->expectExceptionMessage('Cannot use both "cluster" and "sentinel" at the same time.'); RedisAdapter::createConnection($dsn); } @@ -51,6 +51,6 @@ public function testExceptionMessageWhenFailingToRetrieveMasterInformation() $dsn = 'redis:?host['.str_replace(' ', ']&host[', $hosts).']'; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Failed to retrieve master information from sentinel "invalid-masterset-name".'); - AbstractAdapter::createConnection($dsn, ['redis_sentinel' => 'invalid-masterset-name']); + AbstractAdapter::createConnection($dsn, ['sentinel' => 'invalid-masterset-name']); } } diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 480e4f77..09a8e23c 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -46,9 +46,10 @@ trait RedisTrait 'retry_interval' => 0, 'tcp_keepalive' => 0, 'lazy' => null, - 'redis_cluster' => false, - 'relay_cluster_context' => [], 'redis_sentinel' => null, + 'cluster' => false, + 'sentinel' => null, + 'relay_cluster_context' => [], 'dbindex' => 0, 'failover' => 'none', 'ssl' => null, // see https://php.net/context.ssl @@ -90,13 +91,13 @@ private function init(\Redis|Relay|RelayCluster|\RedisArray|\RedisCluster|\Predi */ public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|Relay|RelayCluster { - if (str_starts_with($dsn, 'redis:')) { - $scheme = 'redis'; - } elseif (str_starts_with($dsn, 'rediss:')) { - $scheme = 'rediss'; - } else { - throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:".'); - } + $scheme = match (true) { + str_starts_with($dsn, 'redis:') => 'redis', + str_starts_with($dsn, 'rediss:') => 'rediss', + str_starts_with($dsn, 'valkey:') => 'valkey', + str_starts_with($dsn, 'valkeys:') => 'valkeys', + default => throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:" nor "valkey[s]:".'), + }; if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) { throw new CacheException('Cannot find the "redis" extension nor the "predis/predis" package.'); @@ -124,7 +125,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $query = $hosts = []; - $tls = 'rediss' === $scheme; + $tls = 'rediss' === $scheme || 'valkeys' === $scheme; $tcpScheme = $tls ? 'tls' : 'tcp'; if (isset($params['query'])) { @@ -177,32 +178,41 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $params += $query + $options + self::$defaultConnectionOptions; - if (isset($params['redis_sentinel']) && isset($params['sentinel_master'])) { - throw new InvalidArgumentException('Cannot use both "redis_sentinel" and "sentinel_master" at the same time.'); + $aliases = [ + 'sentinel_master' => 'sentinel', + 'redis_sentinel' => 'sentinel', + 'redis_cluster' => 'cluster', + ]; + foreach ($aliases as $alias => $key) { + $params[$key] = match (true) { + \array_key_exists($key, $query) => $query[$key], + \array_key_exists($alias, $query) => $query[$alias], + \array_key_exists($key, $options) => $options[$key], + \array_key_exists($alias, $options) => $options[$alias], + default => $params[$key], + }; } - $params['redis_sentinel'] ??= $params['sentinel_master'] ?? null; - - if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { + if (isset($params['sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 5.2", "ext-relay".'); } if (isset($params['lazy'])) { $params['lazy'] = filter_var($params['lazy'], \FILTER_VALIDATE_BOOLEAN); } + $params['cluster'] = filter_var($params['cluster'], \FILTER_VALIDATE_BOOLEAN); - $params['redis_cluster'] = filter_var($params['redis_cluster'], \FILTER_VALIDATE_BOOLEAN); - if ($params['redis_cluster'] && isset($params['redis_sentinel'])) { - throw new InvalidArgumentException('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.'); + if ($params['cluster'] && isset($params['sentinel'])) { + throw new InvalidArgumentException('Cannot use both "cluster" and "sentinel" at the same time.'); } $class = $params['class'] ?? match (true) { - $params['redis_cluster'] => match (true) { + $params['cluster'] => match (true) { \extension_loaded('redis') => \RedisCluster::class, \extension_loaded('relay') => RelayCluster::class, default => \Predis\Client::class, }, - isset($params['redis_sentinel']) => match (true) { + isset($params['sentinel']) => match (true) { \extension_loaded('redis') => \Redis::class, \extension_loaded('relay') => Relay::class, default => \Predis\Client::class, @@ -213,7 +223,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra default => \Predis\Client::class, }; - if (isset($params['redis_sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { + if (isset($params['sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { throw new CacheException(\sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class)); } @@ -237,7 +247,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $host = 'tls://'.$host; } - if (!isset($params['redis_sentinel'])) { + if (!isset($params['sentinel'])) { break; } @@ -263,15 +273,15 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $sentinel = @new $sentinelClass($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...$extra); } - if ($address = @$sentinel->getMasterAddrByName($params['redis_sentinel'])) { + if ($address = @$sentinel->getMasterAddrByName($params['sentinel'])) { [$host, $port] = $address; } } catch (\RedisException|\Relay\Exception $redisException) { } } while (++$hostIndex < \count($hosts) && !$address); - if (isset($params['redis_sentinel']) && !$address) { - throw new InvalidArgumentException(\sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']), previous: $redisException ?? null); + if (isset($params['sentinel']) && !$address) { + throw new InvalidArgumentException(\sprintf('Failed to retrieve master information from sentinel "%s".', $params['sentinel']), previous: $redisException ?? null); } try { @@ -446,11 +456,14 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra $redis = $params['lazy'] ? RedisClusterProxy::createLazyProxy($initializer) : $initializer(); } elseif (is_a($class, \Predis\ClientInterface::class, true)) { - if ($params['redis_cluster']) { + if ($params['cluster']) { $params['cluster'] = 'redis'; - } elseif (isset($params['redis_sentinel'])) { + } else { + unset($params['cluster']); + } + if (isset($params['sentinel'])) { $params['replication'] = 'sentinel'; - $params['service'] = $params['redis_sentinel']; + $params['service'] = $params['sentinel']; } $params += ['parameters' => []]; $params['parameters'] += [ @@ -478,7 +491,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } } - if (1 === \count($hosts) && !($params['redis_cluster'] || $params['redis_sentinel'])) { + if (1 === \count($hosts) && !isset($params['cluster']) & !isset($params['sentinel'])) { $hosts = $hosts[0]; } elseif (\in_array($params['failover'], ['slaves', 'distribute'], true) && !isset($params['replication'])) { $params['replication'] = true; @@ -486,8 +499,8 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } $params['exceptions'] = false; - $redis = new $class($hosts, array_diff_key($params, self::$defaultConnectionOptions)); - if (isset($params['redis_sentinel'])) { + $redis = new $class($hosts, array_diff_key($params, array_diff_key(self::$defaultConnectionOptions, ['cluster' => null]))); + if (isset($params['sentinel'])) { $redis->getConnection()->setSentinelTimeout($params['timeout']); } } elseif (class_exists($class, false)) { From 02867f81756a00a6d24ece686f8c851c7f47c9d2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 2 Mar 2025 16:03:52 +0100 Subject: [PATCH 30/44] replace assertEmpty() with stricter assertions --- Tests/Adapter/DoctrineDbalAdapterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Adapter/DoctrineDbalAdapterTest.php b/Tests/Adapter/DoctrineDbalAdapterTest.php index 79752f39..db20b0f3 100644 --- a/Tests/Adapter/DoctrineDbalAdapterTest.php +++ b/Tests/Adapter/DoctrineDbalAdapterTest.php @@ -117,7 +117,7 @@ public function testConfigureSchemaTableExists() $adapter = new DoctrineDbalAdapter($connection); $adapter->configureSchema($schema, $connection, fn () => true); $table = $schema->getTable('cache_items'); - $this->assertEmpty($table->getColumns(), 'The table was not overwritten'); + $this->assertSame([], $table->getColumns(), 'The table was not overwritten'); } /** From 317aa1ad6be9ff1058988e1305b0b1a420c18b38 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Sat, 8 Mar 2025 00:16:33 +0100 Subject: [PATCH 31/44] chore: PHP CS Fixer fixes --- Tests/Adapter/AbstractRedisAdapterTestCase.php | 2 +- Tests/Adapter/PredisReplicationAdapterTest.php | 4 ++-- Tests/Adapter/RelayClusterAdapterTest.php | 4 ++-- Tests/Traits/RedisProxiesTest.php | 3 +-- Traits/RedisTrait.php | 14 +++++++------- Traits/RelayClusterProxy.php | 13 +++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Tests/Adapter/AbstractRedisAdapterTestCase.php b/Tests/Adapter/AbstractRedisAdapterTestCase.php index 03a0f873..c139cc97 100644 --- a/Tests/Adapter/AbstractRedisAdapterTestCase.php +++ b/Tests/Adapter/AbstractRedisAdapterTestCase.php @@ -12,8 +12,8 @@ namespace Symfony\Component\Cache\Tests\Adapter; use Psr\Cache\CacheItemPoolInterface; -use Relay\Relay; use Relay\Cluster as RelayCluster; +use Relay\Relay; use Symfony\Component\Cache\Adapter\RedisAdapter; abstract class AbstractRedisAdapterTestCase extends AdapterTestCase diff --git a/Tests/Adapter/PredisReplicationAdapterTest.php b/Tests/Adapter/PredisReplicationAdapterTest.php index 28af1b5b..b9877234 100644 --- a/Tests/Adapter/PredisReplicationAdapterTest.php +++ b/Tests/Adapter/PredisReplicationAdapterTest.php @@ -27,9 +27,9 @@ public static function setUpBeforeClass(): void $hosts = explode(' ', getenv('REDIS_REPLICATION_HOSTS')); $lastArrayKey = array_key_last($hosts); $hostTable = []; - foreach($hosts as $key => $host) { + foreach ($hosts as $key => $host) { $hostInformation = array_combine(['host', 'port'], explode(':', $host)); - if($lastArrayKey === $key) { + if ($lastArrayKey === $key) { $hostInformation['role'] = 'master'; } $hostTable[] = $hostInformation; diff --git a/Tests/Adapter/RelayClusterAdapterTest.php b/Tests/Adapter/RelayClusterAdapterTest.php index 1f9718a6..56363f82 100644 --- a/Tests/Adapter/RelayClusterAdapterTest.php +++ b/Tests/Adapter/RelayClusterAdapterTest.php @@ -11,9 +11,9 @@ namespace Symfony\Component\Cache\Tests\Adapter; -use Relay\Relay; -use Relay\Cluster as RelayCluster; use Psr\Cache\CacheItemPoolInterface; +use Relay\Cluster as RelayCluster; +use Relay\Relay; use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\Cache\Exception\InvalidArgumentException; diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index 47767a88..051275d6 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -12,8 +12,8 @@ namespace Symfony\Component\Cache\Tests\Traits; use PHPUnit\Framework\TestCase; -use Relay\Relay; use Relay\Cluster as RelayCluster; +use Relay\Relay; use Symfony\Component\Cache\Traits\RedisProxyTrait; use Symfony\Component\Cache\Traits\RelayClusterProxy; use Symfony\Component\Cache\Traits\RelayProxy; @@ -124,7 +124,6 @@ public function testRelayProxy() $this->assertEquals($expectedProxy, $proxy); } - /** * @requires extension relay */ diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 09a8e23c..51c59aa9 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -20,8 +20,8 @@ use Predis\Connection\Replication\ReplicationInterface as Predis2ReplicationInterface; use Predis\Response\ErrorInterface; use Predis\Response\Status; -use Relay\Relay; use Relay\Cluster as RelayCluster; +use Relay\Relay; use Relay\Sentinel; use Symfony\Component\Cache\Exception\CacheException; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -382,20 +382,20 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra try { $relayClusterContext = $params['relay_cluster_context']; - foreach (['allow_self_signed', 'verify_peer_name','verify_peer'] as $contextStreamBoolField) { - if(isset($relayClusterContext['stream'][$contextStreamBoolField])) { + foreach (['allow_self_signed', 'verify_peer_name', 'verify_peer'] as $contextStreamBoolField) { + if (isset($relayClusterContext['stream'][$contextStreamBoolField])) { $relayClusterContext['stream'][$contextStreamBoolField] = filter_var($relayClusterContext['stream'][$contextStreamBoolField], \FILTER_VALIDATE_BOOL); } } - foreach (['use-cache', 'client-tracking','throw-on-error','client-invalidations','reply-literal','persistent'] as $contextBoolField) { - if(isset($relayClusterContext[$contextBoolField])) { + foreach (['use-cache', 'client-tracking', 'throw-on-error', 'client-invalidations', 'reply-literal', 'persistent'] as $contextBoolField) { + if (isset($relayClusterContext[$contextBoolField])) { $relayClusterContext[$contextBoolField] = filter_var($relayClusterContext[$contextBoolField], \FILTER_VALIDATE_BOOL); } } - foreach (['max-retries', 'serializer','compression','compression-level'] as $contextIntField) { - if(isset($relayClusterContext[$contextIntField])) { + foreach (['max-retries', 'serializer', 'compression', 'compression-level'] as $contextIntField) { + if (isset($relayClusterContext[$contextIntField])) { $relayClusterContext[$contextIntField] = filter_var($relayClusterContext[$contextIntField], \FILTER_VALIDATE_INT); } } diff --git a/Traits/RelayClusterProxy.php b/Traits/RelayClusterProxy.php index 92466e56..6d124342 100644 --- a/Traits/RelayClusterProxy.php +++ b/Traits/RelayClusterProxy.php @@ -37,7 +37,7 @@ public function __construct( int|float $command_timeout = 0, bool $persistent = false, #[\SensitiveParameter] mixed $auth = null, - array|null $context = null + array|null $context = null, ) { $this->initializeLazyObject()->__construct(...\func_get_args()); } @@ -157,7 +157,6 @@ public function endpointId(): array|false return $this->initializeLazyObject()->endpointId(...\func_get_args()); } - public function rawCommand(array|string $key_or_address, string $cmd, mixed ...$args): mixed { return $this->initializeLazyObject()->rawCommand(...\func_get_args()); @@ -383,12 +382,13 @@ public function bitpos(mixed $key, int $bit, ?int $start = null, ?int $end = nul return $this->initializeLazyObject()->bitpos(...\func_get_args()); } - public function blmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos, float $timeout): \Relay\Cluster|string|null|false + public function blmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos, float $timeout): \Relay\Cluster|string|false|null { return $this->initializeLazyObject()->blmove(...\func_get_args()); } - public function lmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos): Cluster|string|null|false { + public function lmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos): Cluster|string|false|null + { return $this->initializeLazyObject()->lmove(...\func_get_args()); } @@ -662,7 +662,8 @@ public function ltrim(mixed $key, int $start, int $end): \Relay\Cluster|bool return $this->initializeLazyObject()->ltrim(...\func_get_args()); } - public static function maxMemory(): int { + public static function maxMemory(): int + { return \Relay\Cluster::maxMemory(); } @@ -1083,7 +1084,7 @@ public function zrangestore(mixed $dstkey, mixed $srckey, mixed $start, mixed $e public function zrank(mixed $key, mixed $rank, bool $withscore = false): Cluster|array|int|false { - return $this->initializeLazyObject()->zrank(...\func_get_args()); + return $this->initializeLazyObject()->zrank(...\func_get_args()); } public function zrangebylex(mixed $key, mixed $min, mixed $max, int $offset = -1, int $count = -1): \Relay\Cluster|array|false From 95af448bb7c3d8db02f7b4f5cbf3cb7a6ff1e432 Mon Sep 17 00:00:00 2001 From: COMBROUSE Dimitri Date: Sat, 8 Mar 2025 16:51:34 +0100 Subject: [PATCH 32/44] [Cache] fix data collector --- DataCollector/CacheDataCollector.php | 1 + Tests/DataCollector/CacheDataCollectorTest.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/DataCollector/CacheDataCollector.php b/DataCollector/CacheDataCollector.php index c7f2381e..22a5a039 100644 --- a/DataCollector/CacheDataCollector.php +++ b/DataCollector/CacheDataCollector.php @@ -60,6 +60,7 @@ public function lateCollect(): void $this->data['instances']['statistics'] = $this->calculateStatistics(); $this->data['total']['statistics'] = $this->calculateTotalStatistics(); + $this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']); } public function getName(): string diff --git a/Tests/DataCollector/CacheDataCollectorTest.php b/Tests/DataCollector/CacheDataCollectorTest.php index 68563bfc..7a2f36ab 100644 --- a/Tests/DataCollector/CacheDataCollectorTest.php +++ b/Tests/DataCollector/CacheDataCollectorTest.php @@ -17,6 +17,7 @@ use Symfony\Component\Cache\DataCollector\CacheDataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\VarDumper\Cloner\Data; class CacheDataCollectorTest extends TestCase { @@ -122,6 +123,7 @@ public function testLateCollect() $this->assertEquals($stats[self::INSTANCE_NAME]['hits'], 0, 'hits'); $this->assertEquals($stats[self::INSTANCE_NAME]['misses'], 1, 'misses'); $this->assertEquals($stats[self::INSTANCE_NAME]['calls'], 1, 'calls'); + $this->assertInstanceOf(Data::class, $collector->getCalls()); } private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents) From 3dd8df484ecc6cf29b0797051a296d57c4f38ea6 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 13 Mar 2025 12:44:16 +0100 Subject: [PATCH 33/44] remove legacy "redis_sentinel" option (it was replaced "sentinel") --- Traits/RedisTrait.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 51c59aa9..3d1a0d93 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -46,7 +46,6 @@ trait RedisTrait 'retry_interval' => 0, 'tcp_keepalive' => 0, 'lazy' => null, - 'redis_sentinel' => null, 'cluster' => false, 'sentinel' => null, 'relay_cluster_context' => [], From 382df8bd6ae784144926e95da0dbb120bf27fdd5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 5 Mar 2025 10:13:22 +0100 Subject: [PATCH 34/44] [Cache] Code cleanup --- Tests/Adapter/PredisAdapterTest.php | 4 +- Traits/RedisTrait.php | 80 +++++++++++++---------------- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/Tests/Adapter/PredisAdapterTest.php b/Tests/Adapter/PredisAdapterTest.php index d9afd85a..730bde71 100644 --- a/Tests/Adapter/PredisAdapterTest.php +++ b/Tests/Adapter/PredisAdapterTest.php @@ -42,7 +42,7 @@ public function testCreateConnection() 'scheme' => 'tcp', 'host' => $redisHost[0], 'port' => (int) ($redisHost[1] ?? 6379), - 'persistent' => 0, + 'persistent' => false, 'timeout' => 3, 'read_write_timeout' => 0, 'tcp_nodelay' => true, @@ -74,7 +74,7 @@ public function testCreateSslConnection() 'host' => $redisHost[0], 'port' => (int) ($redisHost[1] ?? 6379), 'ssl' => ['verify_peer' => '0'], - 'persistent' => 0, + 'persistent' => false, 'timeout' => 3, 'read_write_timeout' => 0, 'tcp_nodelay' => true, diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 3d1a0d93..55e7cea6 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -38,17 +38,17 @@ trait RedisTrait { private static array $defaultConnectionOptions = [ 'class' => null, - 'persistent' => 0, + 'persistent' => false, 'persistent_id' => null, 'timeout' => 30, 'read_timeout' => 0, - 'command_timeout' => 0, 'retry_interval' => 0, 'tcp_keepalive' => 0, 'lazy' => null, 'cluster' => false, + 'cluster_command_timeout' => 0, + 'cluster_relay_context' => [], 'sentinel' => null, - 'relay_cluster_context' => [], 'dbindex' => 0, 'failover' => 'none', 'ssl' => null, // see https://php.net/context.ssl @@ -196,10 +196,11 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 5.2", "ext-relay".'); } - if (isset($params['lazy'])) { - $params['lazy'] = filter_var($params['lazy'], \FILTER_VALIDATE_BOOLEAN); + foreach (['lazy', 'persistent', 'cluster'] as $option) { + if (!\is_bool($params[$option] ?? false)) { + $params[$option] = filter_var($params[$option], \FILTER_VALIDATE_BOOLEAN); + } } - $params['cluster'] = filter_var($params['cluster'], \FILTER_VALIDATE_BOOLEAN); if ($params['cluster'] && isset($params['sentinel'])) { throw new InvalidArgumentException('Cannot use both "cluster" and "sentinel" at the same time.'); @@ -285,24 +286,9 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra try { $extra = [ - 'stream' => $params['ssl'] ?? null, - ]; - $booleanStreamOptions = [ - 'allow_self_signed', - 'capture_peer_cert', - 'capture_peer_cert_chain', - 'disable_compression', - 'SNI_enabled', - 'verify_peer', - 'verify_peer_name', + 'stream' => self::filterSslOptions($params['ssl'] ?? []) ?: null, ]; - foreach ($extra['stream'] ?? [] as $streamOption => $value) { - if (\in_array($streamOption, $booleanStreamOptions, true) && \is_string($value)) { - $extra['stream'][$streamOption] = filter_var($value, \FILTER_VALIDATE_BOOL); - } - } - if (isset($params['auth'])) { $extra['auth'] = $params['auth']; } @@ -379,34 +365,27 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } try { - $relayClusterContext = $params['relay_cluster_context']; - - foreach (['allow_self_signed', 'verify_peer_name', 'verify_peer'] as $contextStreamBoolField) { - if (isset($relayClusterContext['stream'][$contextStreamBoolField])) { - $relayClusterContext['stream'][$contextStreamBoolField] = filter_var($relayClusterContext['stream'][$contextStreamBoolField], \FILTER_VALIDATE_BOOL); - } - } - - foreach (['use-cache', 'client-tracking', 'throw-on-error', 'client-invalidations', 'reply-literal', 'persistent'] as $contextBoolField) { - if (isset($relayClusterContext[$contextBoolField])) { - $relayClusterContext[$contextBoolField] = filter_var($relayClusterContext[$contextBoolField], \FILTER_VALIDATE_BOOL); - } - } - - foreach (['max-retries', 'serializer', 'compression', 'compression-level'] as $contextIntField) { - if (isset($relayClusterContext[$contextIntField])) { - $relayClusterContext[$contextIntField] = filter_var($relayClusterContext[$contextIntField], \FILTER_VALIDATE_INT); - } + $context = $params['cluster_relay_context']; + $context['stream'] = self::filterSslOptions($params['ssl'] ?? []) ?: null; + + foreach ($context as $name => $value) { + match ($name) { + 'use-cache', 'client-tracking', 'throw-on-error', 'client-invalidations', 'reply-literal', 'persistent', + => $context[$name] = filter_var($value, \FILTER_VALIDATE_BOOLEAN), + 'max-retries', 'serializer', 'compression', 'compression-level', + => $context[$name] = filter_var($value, \FILTER_VALIDATE_INT), + default => null, + }; } $relayCluster = new $class( name: null, seeds: $hosts, connect_timeout: $params['timeout'], - command_timeout: $params['command_timeout'], - persistent: (bool) $params['persistent'], + command_timeout: $params['cluster_command_timeout'], + persistent: $params['persistent'], auth: $params['auth'] ?? null, - context: $relayClusterContext + context: $context, ); } catch (\Relay\Exception $e) { throw new InvalidArgumentException('Relay cluster connection failed: '.$e->getMessage()); @@ -435,7 +414,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } try { - $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '', ...\defined('Redis::SCAN_PREFIX') ? [$params['ssl'] ?? null] : []); + $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], $params['persistent'], $params['auth'] ?? '', ...\defined('Redis::SCAN_PREFIX') ? [$params['ssl'] ?? null] : []); } catch (\RedisClusterException $e) { throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage()); } @@ -796,4 +775,17 @@ private function getHosts(): array return $hosts; } + + private static function filterSslOptions(array $options): array + { + foreach ($options as $name => $value) { + match ($name) { + 'allow_self_signed', 'capture_peer_cert', 'capture_peer_cert_chain', 'disable_compression', 'SNI_enabled', 'verify_peer', 'verify_peer_name', + => $options[$name] = filter_var($value, \FILTER_VALIDATE_BOOLEAN), + default => null, + }; + } + + return $options; + } } From 82dfb7abdfd28f3227a5dd40544ae72c5bccdcba Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 19 Feb 2025 15:04:36 +0100 Subject: [PATCH 35/44] [Cache] Enable namespace-based invalidation by prefixing keys with backend-native namespace separators --- Adapter/AbstractAdapter.php | 23 +++++-- Adapter/AbstractTagAwareAdapter.php | 38 ++++++++--- Adapter/ArrayAdapter.php | 41 ++++++++++-- Adapter/ChainAdapter.php | 21 +++++- Adapter/DoctrineDbalAdapter.php | 6 +- Adapter/NullAdapter.php | 8 ++- Adapter/PdoAdapter.php | 6 +- Adapter/ProxyAdapter.php | 30 +++++++-- Adapter/RedisTagAwareAdapter.php | 2 +- Adapter/TagAwareAdapter.php | 21 +++++- Adapter/TraceableAdapter.php | 29 ++++++++- CHANGELOG.md | 1 + Exception/BadMethodCallException.php | 25 ++++++++ Tests/Adapter/AdapterTestCase.php | 28 ++++++++ Tests/Adapter/PhpArrayAdapterTest.php | 2 + .../PhpArrayAdapterWithFallbackTest.php | 2 + Tests/Adapter/TagAwareTestTrait.php | 23 +++++++ Tests/Psr16CacheProxyTest.php | 4 +- Traits/AbstractAdapterTrait.php | 64 +++++++++++++------ composer.json | 2 +- 20 files changed, 317 insertions(+), 59 deletions(-) create mode 100644 Exception/BadMethodCallException.php diff --git a/Adapter/AbstractAdapter.php b/Adapter/AbstractAdapter.php index 8cd2218d..2b4bc8b2 100644 --- a/Adapter/AbstractAdapter.php +++ b/Adapter/AbstractAdapter.php @@ -19,11 +19,12 @@ use Symfony\Component\Cache\Traits\AbstractAdapterTrait; use Symfony\Component\Cache\Traits\ContractsTrait; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * @author Nicolas Grekas */ -abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface +abstract class AbstractAdapter implements AdapterInterface, CacheInterface, NamespacedPoolInterface, LoggerAwareInterface, ResettableInterface { use AbstractAdapterTrait; use ContractsTrait; @@ -37,7 +38,19 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg protected function __construct(string $namespace = '', int $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; + if ('' !== $namespace) { + if (str_contains($namespace, static::NS_SEPARATOR)) { + if (str_contains($namespace, static::NS_SEPARATOR.static::NS_SEPARATOR)) { + throw new InvalidArgumentException(\sprintf('Cache namespace "%s" contains empty sub-namespace.', $namespace)); + } + CacheItem::validateKey(str_replace(static::NS_SEPARATOR, '', $namespace)); + } else { + CacheItem::validateKey($namespace); + } + $this->namespace = $namespace.static::NS_SEPARATOR; + } + $this->rootNamespace = $this->namespace; + $this->defaultLifetime = $defaultLifetime; if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); @@ -118,7 +131,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra return MemcachedAdapter::createConnection($dsn, $options); } if (str_starts_with($dsn, 'couchbase:')) { - if (class_exists('CouchbaseBucket') && CouchbaseBucketAdapter::isSupported()) { + if (class_exists(\CouchbaseBucket::class) && CouchbaseBucketAdapter::isSupported()) { return CouchbaseBucketAdapter::createConnection($dsn, $options); } @@ -159,7 +172,7 @@ public function commit(): bool $v = $values[$id]; $type = get_debug_type($v); $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); - CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->rootNamespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } else { foreach ($values as $id => $v) { @@ -182,7 +195,7 @@ public function commit(): bool $ok = false; $type = get_debug_type($v); $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); - CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->rootNamespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } diff --git a/Adapter/AbstractTagAwareAdapter.php b/Adapter/AbstractTagAwareAdapter.php index 822c30f0..23db2b6e 100644 --- a/Adapter/AbstractTagAwareAdapter.php +++ b/Adapter/AbstractTagAwareAdapter.php @@ -17,6 +17,7 @@ use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\AbstractAdapterTrait; use Symfony\Component\Cache\Traits\ContractsTrait; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; /** @@ -30,16 +31,33 @@ * * @internal */ -abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface +abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, AdapterInterface, NamespacedPoolInterface, LoggerAwareInterface, ResettableInterface { use AbstractAdapterTrait; use ContractsTrait; + /** + * @internal + */ + protected const NS_SEPARATOR = ':'; + private const TAGS_PREFIX = "\1tags\1"; protected function __construct(string $namespace = '', int $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; + if ('' !== $namespace) { + if (str_contains($namespace, static::NS_SEPARATOR)) { + if (str_contains($namespace, static::NS_SEPARATOR.static::NS_SEPARATOR)) { + throw new InvalidArgumentException(\sprintf('Cache namespace "%s" contains empty sub-namespace.', $namespace)); + } + CacheItem::validateKey(str_replace(static::NS_SEPARATOR, '', $namespace)); + } else { + CacheItem::validateKey($namespace); + } + $this->namespace = $namespace.static::NS_SEPARATOR; + } + $this->rootNamespace = $this->namespace; + $this->defaultLifetime = $defaultLifetime; if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); @@ -70,7 +88,7 @@ static function ($key, $value, $isHit) { CacheItem::class ); self::$mergeByLifetime ??= \Closure::bind( - static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime) { + static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime, $rootNamespace) { $byLifetime = []; $now = microtime(true); $expiredIds = []; @@ -102,10 +120,10 @@ static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime) $value['tag-operations'] = ['add' => [], 'remove' => []]; $oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? []; foreach (array_diff_key($value['tags'], $oldTags) as $addedTag) { - $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag); + $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag, $rootNamespace); } foreach (array_diff_key($oldTags, $value['tags']) as $removedTag) { - $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag); + $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag, $rootNamespace); } $value['tags'] = array_keys($value['tags']); @@ -168,7 +186,7 @@ protected function doDeleteYieldTags(array $ids): iterable public function commit(): bool { $ok = true; - $byLifetime = (self::$mergeByLifetime)($this->deferred, $expiredIds, $this->getId(...), self::TAGS_PREFIX, $this->defaultLifetime); + $byLifetime = (self::$mergeByLifetime)($this->deferred, $expiredIds, $this->getId(...), self::TAGS_PREFIX, $this->defaultLifetime, $this->rootNamespace); $retry = $this->deferred = []; if ($expiredIds) { @@ -195,7 +213,7 @@ public function commit(): bool $v = $values[$id]; $type = get_debug_type($v); $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); - CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->rootNamespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } else { foreach ($values as $id => $v) { @@ -219,7 +237,7 @@ public function commit(): bool $ok = false; $type = get_debug_type($v); $message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); - CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->rootNamespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } } @@ -244,7 +262,7 @@ public function deleteItems(array $keys): bool try { foreach ($this->doDeleteYieldTags(array_values($ids)) as $id => $tags) { foreach ($tags as $tag) { - $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id; + $tagData[$this->getId(self::TAGS_PREFIX.$tag, $this->rootNamespace)][] = $id; } } } catch (\Exception) { @@ -283,7 +301,7 @@ public function invalidateTags(array $tags): bool $tagIds = []; foreach (array_unique($tags) as $tag) { - $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag); + $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag, $this->rootNamespace); } try { diff --git a/Adapter/ArrayAdapter.php b/Adapter/ArrayAdapter.php index 7b923877..7deb9dc6 100644 --- a/Adapter/ArrayAdapter.php +++ b/Adapter/ArrayAdapter.php @@ -19,6 +19,7 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\ResettableInterface; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * An in-memory cache storage. @@ -27,13 +28,14 @@ * * @author Nicolas Grekas */ -class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface +class ArrayAdapter implements AdapterInterface, CacheInterface, NamespacedPoolInterface, LoggerAwareInterface, ResettableInterface { use LoggerAwareTrait; private array $values = []; private array $tags = []; private array $expiries = []; + private array $subPools = []; private static \Closure $createCacheItem; @@ -226,16 +228,38 @@ public function clear(string $prefix = ''): bool } } - if ($this->values) { - return true; - } + return true; + } + + foreach ($this->subPools as $pool) { + $pool->clear(); } - $this->values = $this->tags = $this->expiries = []; + $this->subPools = $this->values = $this->tags = $this->expiries = []; return true; } + public function withSubNamespace(string $namespace): static + { + CacheItem::validateKey($namespace); + + $subPools = $this->subPools; + + if (isset($subPools[$namespace])) { + return $subPools[$namespace]; + } + + $this->subPools = []; + $clone = clone $this; + $clone->clear(); + + $subPools[$namespace] = $clone; + $this->subPools = $subPools; + + return $clone; + } + /** * Returns all cached values, with cache miss as null. */ @@ -263,6 +287,13 @@ public function reset(): void $this->clear(); } + public function __clone() + { + foreach ($this->subPools as $i => $pool) { + $this->subPools[$i] = clone $pool; + } + } + private function generateItems(array $keys, float $now, \Closure $f): \Generator { foreach ($keys as $i => $key) { diff --git a/Adapter/ChainAdapter.php b/Adapter/ChainAdapter.php index 09fcfdcc..c27faeb1 100644 --- a/Adapter/ChainAdapter.php +++ b/Adapter/ChainAdapter.php @@ -14,11 +14,13 @@ use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\BadMethodCallException; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\ContractsTrait; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\Service\ResetInterface; /** @@ -29,7 +31,7 @@ * * @author Kévin Dunglas */ -class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface +class ChainAdapter implements AdapterInterface, CacheInterface, NamespacedPoolInterface, PruneableInterface, ResettableInterface { use ContractsTrait; @@ -280,6 +282,23 @@ public function prune(): bool return $pruned; } + public function withSubNamespace(string $namespace): static + { + $clone = clone $this; + $adapters = []; + + foreach ($this->adapters as $adapter) { + if (!$adapter instanceof NamespacedPoolInterface) { + throw new BadMethodCallException('All adapters must implement NamespacedPoolInterface to support namespaces.'); + } + + $adapters[] = $adapter->withSubNamespace($namespace); + } + $clone->adapters = $adapters; + + return $clone; + } + public function reset(): void { foreach ($this->adapters as $adapter) { diff --git a/Adapter/DoctrineDbalAdapter.php b/Adapter/DoctrineDbalAdapter.php index c69c777c..7c5379e4 100644 --- a/Adapter/DoctrineDbalAdapter.php +++ b/Adapter/DoctrineDbalAdapter.php @@ -335,17 +335,17 @@ protected function doSave(array $values, int $lifetime): array|bool /** * @internal */ - protected function getId(mixed $key): string + protected function getId(mixed $key, ?string $namespace = null): string { if ('pgsql' !== $this->platformName ??= $this->getPlatformName()) { - return parent::getId($key); + return parent::getId($key, $namespace); } if (str_contains($key, "\0") || str_contains($key, '%') || !preg_match('//u', $key)) { $key = rawurlencode($key); } - return parent::getId($key); + return parent::getId($key, $namespace); } private function getPlatformName(): string diff --git a/Adapter/NullAdapter.php b/Adapter/NullAdapter.php index d5d2ef6b..35553ea1 100644 --- a/Adapter/NullAdapter.php +++ b/Adapter/NullAdapter.php @@ -14,11 +14,12 @@ use Psr\Cache\CacheItemInterface; use Symfony\Component\Cache\CacheItem; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * @author Titouan Galopin */ -class NullAdapter implements AdapterInterface, CacheInterface +class NullAdapter implements AdapterInterface, CacheInterface, NamespacedPoolInterface { private static \Closure $createCacheItem; @@ -94,6 +95,11 @@ public function delete(string $key): bool return $this->deleteItem($key); } + public function withSubNamespace(string $namespace): static + { + return clone $this; + } + private function generateItems(array $keys): \Generator { $f = self::$createCacheItem; diff --git a/Adapter/PdoAdapter.php b/Adapter/PdoAdapter.php index 525e2c6d..7d6cb2df 100644 --- a/Adapter/PdoAdapter.php +++ b/Adapter/PdoAdapter.php @@ -348,17 +348,17 @@ protected function doSave(array $values, int $lifetime): array|bool /** * @internal */ - protected function getId(mixed $key): string + protected function getId(mixed $key, ?string $namespace = null): string { if ('pgsql' !== $this->getDriver()) { - return parent::getId($key); + return parent::getId($key, $namespace); } if (str_contains($key, "\0") || str_contains($key, '%') || !preg_match('//u', $key)) { $key = rawurlencode($key); } - return parent::getId($key); + return parent::getId($key, $namespace); } private function getConnection(): \PDO diff --git a/Adapter/ProxyAdapter.php b/Adapter/ProxyAdapter.php index 56212260..d692dbf3 100644 --- a/Adapter/ProxyAdapter.php +++ b/Adapter/ProxyAdapter.php @@ -19,11 +19,12 @@ use Symfony\Component\Cache\Traits\ContractsTrait; use Symfony\Component\Cache\Traits\ProxyTrait; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * @author Nicolas Grekas */ -class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface +class ProxyAdapter implements AdapterInterface, NamespacedPoolInterface, CacheInterface, PruneableInterface, ResettableInterface { use ContractsTrait; use ProxyTrait; @@ -38,12 +39,17 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0) { - $this->pool = $pool; - $this->poolHash = spl_object_hash($pool); if ('' !== $namespace) { - \assert('' !== CacheItem::validateKey($namespace)); - $this->namespace = $namespace; + if ($pool instanceof NamespacedPoolInterface) { + $pool = $pool->withSubNamespace($namespace); + $this->namespace = $namespace = ''; + } else { + \assert('' !== CacheItem::validateKey($namespace)); + $this->namespace = $namespace; + } } + $this->pool = $pool; + $this->poolHash = spl_object_hash($pool); $this->namespaceLen = \strlen($namespace); $this->defaultLifetime = $defaultLifetime; self::$createCacheItem ??= \Closure::bind( @@ -158,6 +164,20 @@ public function commit(): bool return $this->pool->commit(); } + public function withSubNamespace(string $namespace): static + { + $clone = clone $this; + + if ($clone->pool instanceof NamespacedPoolInterface) { + $clone->pool = $clone->pool->withSubNamespace($namespace); + } else { + $clone->namespace .= CacheItem::validateKey($namespace); + $clone->namespaceLen = \strlen($clone->namespace); + } + + return $clone; + } + private function doSave(CacheItemInterface $item, string $method): bool { if (!$item instanceof CacheItem) { diff --git a/Adapter/RedisTagAwareAdapter.php b/Adapter/RedisTagAwareAdapter.php index a887f29a..779c4d91 100644 --- a/Adapter/RedisTagAwareAdapter.php +++ b/Adapter/RedisTagAwareAdapter.php @@ -159,7 +159,7 @@ protected function doDeleteYieldTags(array $ids): iterable foreach ($results as $id => $result) { if ($result instanceof \RedisException || $result instanceof \Relay\Exception || $result instanceof ErrorInterface) { - CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $result]); + CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->rootNamespace)), 'exception' => $result]); continue; } diff --git a/Adapter/TagAwareAdapter.php b/Adapter/TagAwareAdapter.php index 53c98904..70927cf4 100644 --- a/Adapter/TagAwareAdapter.php +++ b/Adapter/TagAwareAdapter.php @@ -16,9 +16,11 @@ use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\BadMethodCallException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\ContractsTrait; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; /** @@ -33,7 +35,7 @@ * @author Nicolas Grekas * @author Sergey Belyshkin */ -class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface, LoggerAwareInterface +class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, NamespacedPoolInterface, PruneableInterface, ResettableInterface, LoggerAwareInterface { use ContractsTrait; use LoggerAwareTrait; @@ -277,6 +279,23 @@ public function commit(): bool return $ok; } + /** + * @throws BadMethodCallException When the item pool is not a NamespacedPoolInterface + */ + public function withSubNamespace(string $namespace): static + { + if (!$this->pool instanceof NamespacedPoolInterface) { + throw new BadMethodCallException(\sprintf('Cannot call "%s::withSubNamespace()": this class doesn\'t implement "%s".', get_debug_type($this->pool), NamespacedPoolInterface::class)); + } + + $knownTagVersions = &$this->knownTagVersions; // ensures clones share the same array + $clone = clone $this; + $clone->deferred = []; + $clone->pool = $this->pool->withSubNamespace($namespace); + + return $clone; + } + public function prune(): bool { return $this->pool instanceof PruneableInterface && $this->pool->prune(); diff --git a/Adapter/TraceableAdapter.php b/Adapter/TraceableAdapter.php index 8fe6cf37..43628e4c 100644 --- a/Adapter/TraceableAdapter.php +++ b/Adapter/TraceableAdapter.php @@ -13,9 +13,11 @@ use Psr\Cache\CacheItemInterface; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\BadMethodCallException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\Service\ResetInterface; /** @@ -25,8 +27,9 @@ * @author Tobias Nyholm * @author Nicolas Grekas */ -class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface +class TraceableAdapter implements AdapterInterface, CacheInterface, NamespacedPoolInterface, PruneableInterface, ResettableInterface { + private string $namespace = ''; private array $calls = []; public function __construct( @@ -34,10 +37,13 @@ public function __construct( ) { } + /** + * @throws BadMethodCallException When the item pool is not a CacheInterface + */ public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { if (!$this->pool instanceof CacheInterface) { - throw new \BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); + throw new BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); } $isHit = true; @@ -225,11 +231,29 @@ public function getPool(): AdapterInterface return $this->pool; } + /** + * @throws BadMethodCallException When the item pool is not a NamespacedPoolInterface + */ + public function withSubNamespace(string $namespace): static + { + if (!$this->pool instanceof NamespacedPoolInterface) { + throw new BadMethodCallException(\sprintf('Cannot call "%s::withSubNamespace()": this class doesn\'t implement "%s".', get_debug_type($this->pool), NamespacedPoolInterface::class)); + } + + $calls = &$this->calls; // ensures clones share the same array + $clone = clone $this; + $clone->namespace .= CacheItem::validateKey($namespace).':'; + $clone->pool = $this->pool->withSubNamespace($namespace); + + return $clone; + } + protected function start(string $name): TraceableAdapterEvent { $this->calls[] = $event = new TraceableAdapterEvent(); $event->name = $name; $event->start = microtime(true); + $event->namespace = $this->namespace; return $event; } @@ -246,4 +270,5 @@ class TraceableAdapterEvent public array|bool $result; public int $hits = 0; public int $misses = 0; + public string $namespace; } diff --git a/CHANGELOG.md b/CHANGELOG.md index 59195f03..d7b18246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Add support for `\Relay\Cluster` in `RedisAdapter` * Add support for `valkey:` / `valkeys:` schemes + * Add support for namespace-based invalidation * Rename options "redis_cluster" and "redis_sentinel" to "cluster" and "sentinel" respectively 7.2 diff --git a/Exception/BadMethodCallException.php b/Exception/BadMethodCallException.php new file mode 100644 index 00000000..d81f9d26 --- /dev/null +++ b/Exception/BadMethodCallException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Exception; + +use Psr\Cache\CacheException as Psr6CacheInterface; +use Psr\SimpleCache\CacheException as SimpleCacheInterface; + +if (interface_exists(SimpleCacheInterface::class)) { + class BadMethodCallException extends \BadMethodCallException implements Psr6CacheInterface, SimpleCacheInterface + { + } +} else { + class BadMethodCallException extends \BadMethodCallException implements Psr6CacheInterface + { + } +} diff --git a/Tests/Adapter/AdapterTestCase.php b/Tests/Adapter/AdapterTestCase.php index da430296..35eefb50 100644 --- a/Tests/Adapter/AdapterTestCase.php +++ b/Tests/Adapter/AdapterTestCase.php @@ -18,6 +18,7 @@ use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\PruneableInterface; use Symfony\Contracts\Cache\CallbackInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; abstract class AdapterTestCase extends CachePoolTest { @@ -350,6 +351,33 @@ public function testNumericKeysWorkAfterMemoryLeakPrevention() $this->assertEquals('value-50', $cache->getItem((string) 50)->get()); } + + public function testNamespaces() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(0, __FUNCTION__); + + $this->assertInstanceOf(NamespacedPoolInterface::class, $cache); + + $derived = $cache->withSubNamespace('derived'); + + $item = $derived->getItem('foo'); + $derived->save($item->set('Foo')); + + $this->assertFalse($cache->getItem('foo')->isHit()); + + $item = $cache->getItem('bar'); + $cache->save($item->set('Bar')); + + $this->assertFalse($derived->getItem('bar')->isHit()); + $this->assertTrue($cache->getItem('bar')->isHit()); + + $derived = $cache->withSubNamespace('derived'); + $this->assertTrue($derived->getItem('foo')->isHit()); + } } class NotUnserializable diff --git a/Tests/Adapter/PhpArrayAdapterTest.php b/Tests/Adapter/PhpArrayAdapterTest.php index 5bbe4d1d..5bc2bfeb 100644 --- a/Tests/Adapter/PhpArrayAdapterTest.php +++ b/Tests/Adapter/PhpArrayAdapterTest.php @@ -57,6 +57,8 @@ class PhpArrayAdapterTest extends AdapterTestCase 'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.', 'testPrune' => 'PhpArrayAdapter just proxies', + + 'testNamespaces' => 'PhpArrayAdapter does not support namespaces.', ]; protected static string $file; diff --git a/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php index d20ffd55..0f92aee4 100644 --- a/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php +++ b/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php @@ -28,6 +28,8 @@ class PhpArrayAdapterWithFallbackTest extends AdapterTestCase 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testPrune' => 'PhpArrayAdapter just proxies', + + 'testNamespaces' => 'PhpArrayAdapter does not support namespaces.', ]; protected static string $file; diff --git a/Tests/Adapter/TagAwareTestTrait.php b/Tests/Adapter/TagAwareTestTrait.php index 8ec1297e..9894ba00 100644 --- a/Tests/Adapter/TagAwareTestTrait.php +++ b/Tests/Adapter/TagAwareTestTrait.php @@ -183,4 +183,27 @@ public function testRefreshAfterExpires() $cacheItem = $pool->getItem('test'); $this->assertTrue($cacheItem->isHit()); } + + public function testNamespacesAndTags() + { + $pool = $this->createCachePool(); + $pool->clear(); + + $item = $pool->getItem('foo'); + $item->tag('baz'); + $pool->save($item); + + $derived = $pool->withSubNamespace('derived'); + $item = $derived->getItem('bar'); + $item->tag('baz'); + $derived->save($item); + + $this->assertTrue($pool->getItem('foo')->isHit()); + $this->assertTrue($derived->getItem('bar')->isHit()); + + $pool->invalidateTags(['baz']); + + $this->assertFalse($pool->getItem('foo')->isHit()); + $this->assertFalse($derived->getItem('bar')->isHit()); + } } diff --git a/Tests/Psr16CacheProxyTest.php b/Tests/Psr16CacheProxyTest.php index c3d2d8d5..fa771cf9 100644 --- a/Tests/Psr16CacheProxyTest.php +++ b/Tests/Psr16CacheProxyTest.php @@ -45,12 +45,12 @@ public function createSimpleCache(int $defaultLifetime = 0): CacheInterface public function testProxy() { $pool = new ArrayAdapter(); - $cache = new Psr16Cache(new ProxyAdapter($pool, 'my-namespace.')); + $cache = new Psr16Cache(new ProxyAdapter($pool, 'my-namespace')); $this->assertNull($cache->get('some-key')); $this->assertTrue($cache->set('some-other-key', 'value')); - $item = $pool->getItem('my-namespace.some-other-key', 'value'); + $item = $pool->withSubNamespace('my-namespace')->getItem('some-other-key', 'value'); $this->assertTrue($item->isHit()); $this->assertSame('value', $item->get()); } diff --git a/Traits/AbstractAdapterTrait.php b/Traits/AbstractAdapterTrait.php index 6a716743..ac8dc97a 100644 --- a/Traits/AbstractAdapterTrait.php +++ b/Traits/AbstractAdapterTrait.php @@ -35,6 +35,7 @@ trait AbstractAdapterTrait */ private static \Closure $mergeByLifetime; + private readonly string $rootNamespace; private string $namespace = ''; private int $defaultLifetime; private string $namespaceVersion = ''; @@ -106,15 +107,16 @@ public function clear(string $prefix = ''): bool { $this->deferred = []; if ($cleared = $this->versioningIsEnabled) { + $rootNamespace = $this->rootNamespace ??= $this->namespace; if ('' === $namespaceVersionToClear = $this->namespaceVersion) { - foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) { + foreach ($this->doFetch([static::NS_SEPARATOR.$rootNamespace]) as $v) { $namespaceVersionToClear = $v; } } - $namespaceToClear = $this->namespace.$namespaceVersionToClear; + $namespaceToClear = $rootNamespace.$namespaceVersionToClear; $namespaceVersion = self::formatNamespaceVersion(mt_rand()); try { - $e = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0); + $e = $this->doSave([static::NS_SEPARATOR.$rootNamespace => $namespaceVersion], 0); } catch (\Exception $e) { } if (true !== $e && [] !== $e) { @@ -247,6 +249,16 @@ public function saveDeferred(CacheItemInterface $item): bool return true; } + public function withSubNamespace(string $namespace): static + { + $this->rootNamespace ??= $this->namespace; + + $clone = clone $this; + $clone->namespace .= CacheItem::validateKey($namespace).static::NS_SEPARATOR; + + return $clone; + } + /** * Enables/disables versioning of items. * @@ -318,19 +330,24 @@ private function generateItems(iterable $items, array &$keys): \Generator /** * @internal */ - protected function getId(mixed $key): string + protected function getId(mixed $key, ?string $namespace = null): string { - if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { + $namespace ??= $this->namespace; + + if ('' !== $this->namespaceVersion) { + $namespace .= $this->namespaceVersion; + } elseif ($this->versioningIsEnabled) { + $rootNamespace = $this->rootNamespace ??= $this->namespace; $this->ids = []; $this->namespaceVersion = '1'.static::NS_SEPARATOR; try { - foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) { + foreach ($this->doFetch([static::NS_SEPARATOR.$rootNamespace]) as $v) { $this->namespaceVersion = $v; } $e = true; if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) { $this->namespaceVersion = self::formatNamespaceVersion(time()); - $e = $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0); + $e = $this->doSave([static::NS_SEPARATOR.$rootNamespace => $this->namespaceVersion], 0); } } catch (\Exception $e) { } @@ -338,25 +355,34 @@ protected function getId(mixed $key): string $message = 'Failed to save the new namespace'.($e instanceof \Exception ? ': '.$e->getMessage() : '.'); CacheItem::log($this->logger, $message, ['exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]); } + + $namespace .= $this->namespaceVersion; } if (\is_string($key) && isset($this->ids[$key])) { - return $this->namespace.$this->namespaceVersion.$this->ids[$key]; - } - \assert('' !== CacheItem::validateKey($key)); - $this->ids[$key] = $key; + $id = $this->ids[$key]; + } else { + \assert('' !== CacheItem::validateKey($key)); + $this->ids[$key] = $key; - if (\count($this->ids) > 1000) { - $this->ids = \array_slice($this->ids, 500, null, true); // stop memory leak if there are many keys - } + if (\count($this->ids) > 1000) { + $this->ids = \array_slice($this->ids, 500, null, true); // stop memory leak if there are many keys + } + + if (null === $this->maxIdLength) { + return $namespace.$key; + } + if (\strlen($id = $namespace.$key) <= $this->maxIdLength) { + return $id; + } - if (null === $this->maxIdLength) { - return $this->namespace.$this->namespaceVersion.$key; - } - if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { // Use xxh128 to favor speed over security, which is not an issue here $this->ids[$key] = $id = substr_replace(base64_encode(hash('xxh128', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 2)); - $id = $this->namespace.$this->namespaceVersion.$id; + } + $id = $namespace.$id; + + if (null !== $this->maxIdLength && \strlen($id) > $this->maxIdLength) { + return base64_encode(hash('xxh128', $id, true)); } return $id; diff --git a/composer.json b/composer.json index bdb461be..c89d6672 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "php": ">=8.2", "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", - "symfony/cache-contracts": "^2.5|^3", + "symfony/cache-contracts": "^3.6", "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/service-contracts": "^2.5|^3", "symfony/var-exporter": "^6.4|^7.0" From d68bb7363a6a6a7ef621ad8756f0ddd7f2d6b930 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 15 Mar 2025 14:10:48 +0100 Subject: [PATCH 36/44] Various cleanups --- Tests/Traits/RedisProxiesTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Tests/Traits/RedisProxiesTest.php b/Tests/Traits/RedisProxiesTest.php index 051275d6..50f784da 100644 --- a/Tests/Traits/RedisProxiesTest.php +++ b/Tests/Traits/RedisProxiesTest.php @@ -17,7 +17,6 @@ use Symfony\Component\Cache\Traits\RedisProxyTrait; use Symfony\Component\Cache\Traits\RelayClusterProxy; use Symfony\Component\Cache\Traits\RelayProxy; -use Symfony\Component\VarExporter\LazyProxyTrait; use Symfony\Component\VarExporter\ProxyHelper; class RedisProxiesTest extends TestCase @@ -37,7 +36,7 @@ public function testRedisProxy($class) $methods = []; foreach ((new \ReflectionClass(\sprintf('Symfony\Component\Cache\Traits\\%s%dProxy', $class, $version)))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name)) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name)) { continue; } $return = '__construct' === $method->name || $method->getReturnType() instanceof \ReflectionNamedType && 'void' === (string) $method->getReturnType() ? '' : 'return '; @@ -89,7 +88,7 @@ public function testRelayProxy() $expectedMethods = []; foreach ((new \ReflectionClass(RelayProxy::class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { continue; } @@ -136,7 +135,7 @@ public function testRelayClusterProxy() $expectedMethods = []; foreach ((new \ReflectionClass(RelayClusterProxy::class))->getMethods() as $method) { - if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name) || $method->isStatic()) { + if ('reset' === $method->name || method_exists(RedisProxyTrait::class, $method->name) || $method->isStatic()) { continue; } From 66e51fb8aafb1211064f86570a30cca9d9076d21 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Thu, 13 Mar 2025 23:58:12 +0100 Subject: [PATCH 37/44] chore: PHP CS Fixer fixes --- Traits/RedisTrait.php | 2 +- Traits/RelayClusterProxy.php | 314 +++++++++++++++++------------------ 2 files changed, 158 insertions(+), 158 deletions(-) diff --git a/Traits/RedisTrait.php b/Traits/RedisTrait.php index 55e7cea6..19b4b911 100644 --- a/Traits/RedisTrait.php +++ b/Traits/RedisTrait.php @@ -692,7 +692,7 @@ private function pipeline(\Closure $generator, ?object $redis = null): \Generato $ids = []; $redis ??= $this->redis; - if ($redis instanceof \RedisCluster || $redis instanceof \Relay\Cluster || ($redis instanceof \Predis\ClientInterface && ($redis->getConnection() instanceof RedisCluster || $redis->getConnection() instanceof Predis2RedisCluster))) { + if ($redis instanceof \RedisCluster || $redis instanceof RelayCluster || ($redis instanceof \Predis\ClientInterface && ($redis->getConnection() instanceof RedisCluster || $redis->getConnection() instanceof Predis2RedisCluster))) { // phpredis & predis don't support pipelining with RedisCluster // \Relay\Cluster does not support multi with pipeline mode // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining diff --git a/Traits/RelayClusterProxy.php b/Traits/RelayClusterProxy.php index 6d124342..fd5f08b5 100644 --- a/Traits/RelayClusterProxy.php +++ b/Traits/RelayClusterProxy.php @@ -24,7 +24,7 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); /** * @internal */ -class RelayClusterProxy extends \Relay\Cluster implements ResetInterface, LazyObjectInterface +class RelayClusterProxy extends Cluster implements ResetInterface, LazyObjectInterface { use RedisProxyTrait { resetLazyObject as reset; @@ -67,7 +67,7 @@ public function dispatchEvents(): false|int return $this->initializeLazyObject()->dispatchEvents(...\func_get_args()); } - public function dump(mixed $key): \Relay\Cluster|string|false + public function dump(mixed $key): Cluster|string|false { return $this->initializeLazyObject()->dump(...\func_get_args()); } @@ -87,7 +87,7 @@ public function getTransferredBytes(): array|false return $this->initializeLazyObject()->getTransferredBytes(...\func_get_args()); } - public function getrange(mixed $key, int $start, int $end): \Relay\Cluster|string|false + public function getrange(mixed $key, int $start, int $end): Cluster|string|false { return $this->initializeLazyObject()->getrange(...\func_get_args()); } @@ -167,42 +167,42 @@ public function cluster(array|string $key_or_address, string $operation, mixed . return $this->initializeLazyObject()->cluster(...\func_get_args()); } - public function info(array|string $key_or_address, string ...$sections): \Relay\Cluster|array|false + public function info(array|string $key_or_address, string ...$sections): Cluster|array|false { return $this->initializeLazyObject()->info(...\func_get_args()); } - public function flushdb(array|string $key_or_address, bool|null $sync = null): \Relay\Cluster|bool + public function flushdb(array|string $key_or_address, bool|null $sync = null): Cluster|bool { return $this->initializeLazyObject()->flushdb(...\func_get_args()); } - public function flushall(array|string $key_or_address, bool|null $sync = null): \Relay\Cluster|bool + public function flushall(array|string $key_or_address, bool|null $sync = null): Cluster|bool { return $this->initializeLazyObject()->flushall(...\func_get_args()); } - public function dbsize(array|string $key_or_address): \Relay\Cluster|int|false + public function dbsize(array|string $key_or_address): Cluster|int|false { return $this->initializeLazyObject()->dbsize(...\func_get_args()); } - public function waitaof(array|string $key_or_address, int $numlocal, int $numremote, int $timeout): \Relay\Relay|array|false + public function waitaof(array|string $key_or_address, int $numlocal, int $numremote, int $timeout): Relay|array|false { return $this->initializeLazyObject()->waitaof(...\func_get_args()); } - public function restore(mixed $key, int $ttl, string $value, array|null $options = null): \Relay\Cluster|bool + public function restore(mixed $key, int $ttl, string $value, array|null $options = null): Cluster|bool { return $this->initializeLazyObject()->restore(...\func_get_args()); } - public function echo(array|string $key_or_address, string $message): \Relay\Cluster|string|false + public function echo(array|string $key_or_address, string $message): Cluster|string|false { return $this->initializeLazyObject()->echo(...\func_get_args()); } - public function ping(array|string $key_or_address, string|null $message = null): \Relay\Cluster|bool|string + public function ping(array|string $key_or_address, string|null $message = null): Cluster|bool|string { return $this->initializeLazyObject()->ping(...\func_get_args()); } @@ -212,22 +212,22 @@ public function idleTime(): int return $this->initializeLazyObject()->idleTime(...\func_get_args()); } - public function randomkey(array|string $key_or_address): \Relay\Cluster|bool|string + public function randomkey(array|string $key_or_address): Cluster|bool|string { return $this->initializeLazyObject()->randomkey(...\func_get_args()); } - public function time(array|string $key_or_address): \Relay\Cluster|array|false + public function time(array|string $key_or_address): Cluster|array|false { return $this->initializeLazyObject()->time(...\func_get_args()); } - public function bgrewriteaof(array|string $key_or_address): \Relay\Cluster|bool + public function bgrewriteaof(array|string $key_or_address): Cluster|bool { return $this->initializeLazyObject()->bgrewriteaof(...\func_get_args()); } - public function lastsave(array|string $key_or_address): \Relay\Cluster|false|int + public function lastsave(array|string $key_or_address): Cluster|false|int { return $this->initializeLazyObject()->lastsave(...\func_get_args()); } @@ -237,32 +237,32 @@ public function lcs(mixed $key1, mixed $key2, array|null $options = null): mixed return $this->initializeLazyObject()->lcs(...\func_get_args()); } - public function bgsave(array|string $key_or_address, bool $schedule = false): \Relay\Cluster|bool + public function bgsave(array|string $key_or_address, bool $schedule = false): Cluster|bool { return $this->initializeLazyObject()->bgsave(...\func_get_args()); } - public function save(array|string $key_or_address): \Relay\Cluster|bool + public function save(array|string $key_or_address): Cluster|bool { return $this->initializeLazyObject()->save(...\func_get_args()); } - public function role(array|string $key_or_address): \Relay\Cluster|array|false + public function role(array|string $key_or_address): Cluster|array|false { return $this->initializeLazyObject()->role(...\func_get_args()); } - public function ttl(mixed $key): \Relay\Cluster|false|int + public function ttl(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->ttl(...\func_get_args()); } - public function pttl(mixed $key): \Relay\Cluster|false|int + public function pttl(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->pttl(...\func_get_args()); } - public function exists(mixed ...$keys): \Relay\Cluster|bool|int + public function exists(mixed ...$keys): Cluster|bool|int { return $this->initializeLazyObject()->exists(...\func_get_args()); } @@ -292,17 +292,17 @@ public function client(array|string $key_or_address, string $operation, mixed .. return $this->initializeLazyObject()->client(...\func_get_args()); } - public function geoadd(mixed $key, float $lng, float $lat, string $member, mixed ...$other_triples_and_options): \Relay\Cluster|false|int + public function geoadd(mixed $key, float $lng, float $lat, string $member, mixed ...$other_triples_and_options): Cluster|false|int { return $this->initializeLazyObject()->geoadd(...\func_get_args()); } - public function geodist(mixed $key, string $src, string $dst, string|null $unit = null): \Relay\Cluster|float|false + public function geodist(mixed $key, string $src, string $dst, string|null $unit = null): Cluster|float|false { return $this->initializeLazyObject()->geodist(...\func_get_args()); } - public function geohash(mixed $key, string $member, string ...$other_members): \Relay\Cluster|array|false + public function geohash(mixed $key, string $member, string ...$other_members): Cluster|array|false { return $this->initializeLazyObject()->geohash(...\func_get_args()); } @@ -327,12 +327,12 @@ public function georadius_ro(mixed $key, float $lng, float $lat, float $radius, return $this->initializeLazyObject()->georadius_ro(...\func_get_args()); } - public function geosearchstore(mixed $dstkey, mixed $srckey, array|string $position, array|int|float $shape, string $unit, array $options = []): \Relay\Cluster|false|int + public function geosearchstore(mixed $dstkey, mixed $srckey, array|string $position, array|int|float $shape, string $unit, array $options = []): Cluster|false|int { return $this->initializeLazyObject()->geosearchstore(...\func_get_args()); } - public function geosearch(mixed $key, array|string $position, array|int|float $shape, string $unit, array $options = []): \Relay\Cluster|array|false + public function geosearch(mixed $key, array|string $position, array|int|float $shape, string $unit, array $options = []): Cluster|array|false { return $this->initializeLazyObject()->geosearch(...\func_get_args()); } @@ -347,17 +347,17 @@ public function getset(mixed $key, mixed $value): mixed return $this->initializeLazyObject()->getset(...\func_get_args()); } - public function setrange(mixed $key, int $start, mixed $value): \Relay\Cluster|false|int + public function setrange(mixed $key, int $start, mixed $value): Cluster|false|int { return $this->initializeLazyObject()->setrange(...\func_get_args()); } - public function getbit(mixed $key, int $pos): \Relay\Cluster|false|int + public function getbit(mixed $key, int $pos): Cluster|false|int { return $this->initializeLazyObject()->getbit(...\func_get_args()); } - public function bitcount(mixed $key, int $start = 0, int $end = -1, bool $by_bit = false): \Relay\Cluster|false|int + public function bitcount(mixed $key, int $start = 0, int $end = -1, bool $by_bit = false): Cluster|false|int { return $this->initializeLazyObject()->bitcount(...\func_get_args()); } @@ -367,22 +367,22 @@ public function config(array|string $key_or_address, string $operation, mixed .. return $this->initializeLazyObject()->config(...\func_get_args()); } - public function command(mixed ...$args): \Relay\Cluster|array|false|int + public function command(mixed ...$args): Cluster|array|false|int { return $this->initializeLazyObject()->command(...\func_get_args()); } - public function bitop(string $operation, string $dstkey, string $srckey, string ...$other_keys): \Relay\Cluster|false|int + public function bitop(string $operation, string $dstkey, string $srckey, string ...$other_keys): Cluster|false|int { return $this->initializeLazyObject()->bitop(...\func_get_args()); } - public function bitpos(mixed $key, int $bit, ?int $start = null, ?int $end = null, bool $by_bit = false): \Relay\Cluster|false|int + public function bitpos(mixed $key, int $bit, ?int $start = null, ?int $end = null, bool $by_bit = false): Cluster|false|int { return $this->initializeLazyObject()->bitpos(...\func_get_args()); } - public function blmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos, float $timeout): \Relay\Cluster|string|false|null + public function blmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstpos, float $timeout): Cluster|string|false|null { return $this->initializeLazyObject()->blmove(...\func_get_args()); } @@ -392,7 +392,7 @@ public function lmove(mixed $srckey, mixed $dstkey, string $srcpos, string $dstp return $this->initializeLazyObject()->lmove(...\func_get_args()); } - public function setbit(mixed $key, int $pos, int $value): \Relay\Cluster|false|int + public function setbit(mixed $key, int $pos, int $value): Cluster|false|int { return $this->initializeLazyObject()->setbit(...\func_get_args()); } @@ -402,12 +402,12 @@ public function acl(array|string $key_or_address, string $operation, string ...$ return $this->initializeLazyObject()->acl(...\func_get_args()); } - public function append(mixed $key, mixed $value): \Relay\Cluster|false|int + public function append(mixed $key, mixed $value): Cluster|false|int { return $this->initializeLazyObject()->append(...\func_get_args()); } - public function set(mixed $key, mixed $value, mixed $options = null): \Relay\Cluster|string|bool + public function set(mixed $key, mixed $value, mixed $options = null): Cluster|string|bool { return $this->initializeLazyObject()->set(...\func_get_args()); } @@ -417,32 +417,32 @@ public function getex(mixed $key, ?array $options = null): mixed return $this->initializeLazyObject()->getex(...\func_get_args()); } - public function setex(mixed $key, int $seconds, mixed $value): \Relay\Cluster|bool + public function setex(mixed $key, int $seconds, mixed $value): Cluster|bool { return $this->initializeLazyObject()->setex(...\func_get_args()); } - public function pfadd(mixed $key, array $elements): \Relay\Cluster|false|int + public function pfadd(mixed $key, array $elements): Cluster|false|int { return $this->initializeLazyObject()->pfadd(...\func_get_args()); } - public function pfcount(mixed $key): \Relay\Cluster|int|false + public function pfcount(mixed $key): Cluster|int|false { return $this->initializeLazyObject()->pfcount(...\func_get_args()); } - public function pfmerge(string $dstkey, array $srckeys): \Relay\Cluster|bool + public function pfmerge(string $dstkey, array $srckeys): Cluster|bool { return $this->initializeLazyObject()->pfmerge(...\func_get_args()); } - public function psetex(mixed $key, int $milliseconds, mixed $value): \Relay\Cluster|bool + public function psetex(mixed $key, int $milliseconds, mixed $value): Cluster|bool { return $this->initializeLazyObject()->psetex(...\func_get_args()); } - public function publish(string $channel, string $message): \Relay\Cluster|false|int + public function publish(string $channel, string $message): Cluster|false|int { return $this->initializeLazyObject()->publish(...\func_get_args()); } @@ -452,117 +452,117 @@ public function pubsub(array|string $key_or_address, string $operation, mixed .. return $this->initializeLazyObject()->pubsub(...\func_get_args()); } - public function setnx(mixed $key, mixed $value): \Relay\Cluster|bool + public function setnx(mixed $key, mixed $value): Cluster|bool { return $this->initializeLazyObject()->setnx(...\func_get_args()); } - public function mget(array $keys): \Relay\Cluster|array|false + public function mget(array $keys): Cluster|array|false { return $this->initializeLazyObject()->mget(...\func_get_args()); } - public function mset(array $kvals): \Relay\Cluster|array|bool + public function mset(array $kvals): Cluster|array|bool { return $this->initializeLazyObject()->mset(...\func_get_args()); } - public function msetnx(array $kvals): \Relay\Cluster|array|bool + public function msetnx(array $kvals): Cluster|array|bool { return $this->initializeLazyObject()->msetnx(...\func_get_args()); } - public function rename(mixed $key, mixed $newkey): \Relay\Cluster|bool + public function rename(mixed $key, mixed $newkey): Cluster|bool { return $this->initializeLazyObject()->rename(...\func_get_args()); } - public function renamenx(mixed $key, mixed $newkey): \Relay\Cluster|bool + public function renamenx(mixed $key, mixed $newkey): Cluster|bool { return $this->initializeLazyObject()->renamenx(...\func_get_args()); } - public function del(mixed ...$keys): \Relay\Cluster|bool|int + public function del(mixed ...$keys): Cluster|bool|int { return $this->initializeLazyObject()->del(...\func_get_args()); } - public function unlink(mixed ...$keys): \Relay\Cluster|false|int + public function unlink(mixed ...$keys): Cluster|false|int { return $this->initializeLazyObject()->unlink(...\func_get_args()); } - public function expire(mixed $key, int $seconds, string|null $mode = null): \Relay\Cluster|bool + public function expire(mixed $key, int $seconds, string|null $mode = null): Cluster|bool { return $this->initializeLazyObject()->expire(...\func_get_args()); } - public function pexpire(mixed $key, int $milliseconds): \Relay\Cluster|bool + public function pexpire(mixed $key, int $milliseconds): Cluster|bool { return $this->initializeLazyObject()->pexpire(...\func_get_args()); } - public function expireat(mixed $key, int $timestamp): \Relay\Cluster|bool + public function expireat(mixed $key, int $timestamp): Cluster|bool { return $this->initializeLazyObject()->expireat(...\func_get_args()); } - public function expiretime(mixed $key): \Relay\Cluster|false|int + public function expiretime(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->expiretime(...\func_get_args()); } - public function pexpireat(mixed $key, int $timestamp_ms): \Relay\Cluster|bool + public function pexpireat(mixed $key, int $timestamp_ms): Cluster|bool { return $this->initializeLazyObject()->pexpireat(...\func_get_args()); } public static function flushMemory(?string $endpointId = null, ?int $db = null): bool { - return \Relay\Cluster::flushMemory(...\func_get_args()); + return Cluster::flushMemory(...\func_get_args()); } - public function pexpiretime(mixed $key): \Relay\Cluster|false|int + public function pexpiretime(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->pexpiretime(...\func_get_args()); } - public function persist(mixed $key): \Relay\Cluster|bool + public function persist(mixed $key): Cluster|bool { return $this->initializeLazyObject()->persist(...\func_get_args()); } - public function type(mixed $key): \Relay\Cluster|bool|int|string + public function type(mixed $key): Cluster|bool|int|string { return $this->initializeLazyObject()->type(...\func_get_args()); } - public function lrange(mixed $key, int $start, int $stop): \Relay\Cluster|array|false + public function lrange(mixed $key, int $start, int $stop): Cluster|array|false { return $this->initializeLazyObject()->lrange(...\func_get_args()); } - public function lpush(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function lpush(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->lpush(...\func_get_args()); } - public function rpush(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function rpush(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->rpush(...\func_get_args()); } - public function lpushx(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function lpushx(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->lpushx(...\func_get_args()); } - public function rpushx(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function rpushx(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->rpushx(...\func_get_args()); } - public function lset(mixed $key, int $index, mixed $member): \Relay\Cluster|bool + public function lset(mixed $key, int $index, mixed $member): Cluster|bool { return $this->initializeLazyObject()->lset(...\func_get_args()); } @@ -592,7 +592,7 @@ public function brpoplpush(mixed $srckey, mixed $dstkey, float $timeout): mixed return $this->initializeLazyObject()->brpoplpush(...\func_get_args()); } - public function blpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + public function blpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): Cluster|array|false|null { return $this->initializeLazyObject()->blpop(...\func_get_args()); } @@ -602,7 +602,7 @@ public function blmpop(float $timeout, array $keys, string $from, int $count = 1 return $this->initializeLazyObject()->blmpop(...\func_get_args()); } - public function bzmpop(float $timeout, array $keys, string $from, int $count = 1): \Relay\Cluster|array|false|null + public function bzmpop(float $timeout, array $keys, string $from, int $count = 1): Cluster|array|false|null { return $this->initializeLazyObject()->bzmpop(...\func_get_args()); } @@ -612,22 +612,22 @@ public function lmpop(array $keys, string $from, int $count = 1): mixed return $this->initializeLazyObject()->lmpop(...\func_get_args()); } - public function zmpop(array $keys, string $from, int $count = 1): \Relay\Cluster|array|false|null + public function zmpop(array $keys, string $from, int $count = 1): Cluster|array|false|null { return $this->initializeLazyObject()->zmpop(...\func_get_args()); } - public function brpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + public function brpop(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): Cluster|array|false|null { return $this->initializeLazyObject()->brpop(...\func_get_args()); } - public function bzpopmax(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + public function bzpopmax(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): Cluster|array|false|null { return $this->initializeLazyObject()->bzpopmax(...\func_get_args()); } - public function bzpopmin(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): \Relay\Cluster|array|false|null + public function bzpopmin(string|array $key, string|float $timeout_or_key, mixed ...$extra_args): Cluster|array|false|null { return $this->initializeLazyObject()->bzpopmin(...\func_get_args()); } @@ -637,12 +637,12 @@ public function object(string $op, mixed $key): mixed return $this->initializeLazyObject()->object(...\func_get_args()); } - public function geopos(mixed $key, mixed ...$members): \Relay\Cluster|array|false + public function geopos(mixed $key, mixed ...$members): Cluster|array|false { return $this->initializeLazyObject()->geopos(...\func_get_args()); } - public function lrem(mixed $key, mixed $member, int $count = 0): \Relay\Cluster|false|int + public function lrem(mixed $key, mixed $member, int $count = 0): Cluster|false|int { return $this->initializeLazyObject()->lrem(...\func_get_args()); } @@ -652,19 +652,19 @@ public function lindex(mixed $key, int $index): mixed return $this->initializeLazyObject()->lindex(...\func_get_args()); } - public function linsert(mixed $key, string $op, mixed $pivot, mixed $element): \Relay\Cluster|false|int + public function linsert(mixed $key, string $op, mixed $pivot, mixed $element): Cluster|false|int { return $this->initializeLazyObject()->linsert(...\func_get_args()); } - public function ltrim(mixed $key, int $start, int $end): \Relay\Cluster|bool + public function ltrim(mixed $key, int $start, int $end): Cluster|bool { return $this->initializeLazyObject()->ltrim(...\func_get_args()); } public static function maxMemory(): int { - return \Relay\Cluster::maxMemory(); + return Cluster::maxMemory(); } public function hget(mixed $key, mixed $member): mixed @@ -672,127 +672,127 @@ public function hget(mixed $key, mixed $member): mixed return $this->initializeLazyObject()->hget(...\func_get_args()); } - public function hstrlen(mixed $key, mixed $member): \Relay\Cluster|false|int + public function hstrlen(mixed $key, mixed $member): Cluster|false|int { return $this->initializeLazyObject()->hstrlen(...\func_get_args()); } - public function hgetall(mixed $key): \Relay\Cluster|array|false + public function hgetall(mixed $key): Cluster|array|false { return $this->initializeLazyObject()->hgetall(...\func_get_args()); } - public function hkeys(mixed $key): \Relay\Cluster|array|false + public function hkeys(mixed $key): Cluster|array|false { return $this->initializeLazyObject()->hkeys(...\func_get_args()); } - public function hvals(mixed $key): \Relay\Cluster|array|false + public function hvals(mixed $key): Cluster|array|false { return $this->initializeLazyObject()->hvals(...\func_get_args()); } - public function hmget(mixed $key, array $members): \Relay\Cluster|array|false + public function hmget(mixed $key, array $members): Cluster|array|false { return $this->initializeLazyObject()->hmget(...\func_get_args()); } - public function hmset(mixed $key, array $members): \Relay\Cluster|bool + public function hmset(mixed $key, array $members): Cluster|bool { return $this->initializeLazyObject()->hmset(...\func_get_args()); } - public function hexists(mixed $key, mixed $member): \Relay\Cluster|bool + public function hexists(mixed $key, mixed $member): Cluster|bool { return $this->initializeLazyObject()->hexists(...\func_get_args()); } - public function hrandfield(mixed $key, array|null $options = null): \Relay\Cluster|array|string|false + public function hrandfield(mixed $key, array|null $options = null): Cluster|array|string|false { return $this->initializeLazyObject()->hrandfield(...\func_get_args()); } - public function hsetnx(mixed $key, mixed $member, mixed $value): \Relay\Cluster|bool + public function hsetnx(mixed $key, mixed $member, mixed $value): Cluster|bool { return $this->initializeLazyObject()->hsetnx(...\func_get_args()); } - public function hset(mixed $key, mixed ...$keys_and_vals): \Relay\Cluster|int|false + public function hset(mixed $key, mixed ...$keys_and_vals): Cluster|int|false { return $this->initializeLazyObject()->hset(...\func_get_args()); } - public function hdel(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function hdel(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->hdel(...\func_get_args()); } - public function hincrby(mixed $key, mixed $member, int $value): \Relay\Cluster|false|int + public function hincrby(mixed $key, mixed $member, int $value): Cluster|false|int { return $this->initializeLazyObject()->hincrby(...\func_get_args()); } - public function hincrbyfloat(mixed $key, mixed $member, float $value): \Relay\Cluster|bool|float + public function hincrbyfloat(mixed $key, mixed $member, float $value): Cluster|bool|float { return $this->initializeLazyObject()->hincrbyfloat(...\func_get_args()); } - public function incr(mixed $key, int $by = 1): \Relay\Cluster|false|int + public function incr(mixed $key, int $by = 1): Cluster|false|int { return $this->initializeLazyObject()->incr(...\func_get_args()); } - public function decr(mixed $key, int $by = 1): \Relay\Cluster|false|int + public function decr(mixed $key, int $by = 1): Cluster|false|int { return $this->initializeLazyObject()->decr(...\func_get_args()); } - public function incrby(mixed $key, int $value): \Relay\Cluster|false|int + public function incrby(mixed $key, int $value): Cluster|false|int { return $this->initializeLazyObject()->incrby(...\func_get_args()); } - public function decrby(mixed $key, int $value): \Relay\Cluster|false|int + public function decrby(mixed $key, int $value): Cluster|false|int { return $this->initializeLazyObject()->decrby(...\func_get_args()); } - public function incrbyfloat(mixed $key, float $value): \Relay\Cluster|false|float + public function incrbyfloat(mixed $key, float $value): Cluster|false|float { return $this->initializeLazyObject()->incrbyfloat(...\func_get_args()); } - public function sdiff(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + public function sdiff(mixed $key, mixed ...$other_keys): Cluster|array|false { return $this->initializeLazyObject()->sdiff(...\func_get_args()); } - public function sdiffstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + public function sdiffstore(mixed $key, mixed ...$other_keys): Cluster|false|int { return $this->initializeLazyObject()->sdiffstore(...\func_get_args()); } - public function sinter(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + public function sinter(mixed $key, mixed ...$other_keys): Cluster|array|false { return $this->initializeLazyObject()->sinter(...\func_get_args()); } - public function sintercard(array $keys, int $limit = -1): \Relay\Cluster|false|int + public function sintercard(array $keys, int $limit = -1): Cluster|false|int { return $this->initializeLazyObject()->sintercard(...\func_get_args()); } - public function sinterstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + public function sinterstore(mixed $key, mixed ...$other_keys): Cluster|false|int { return $this->initializeLazyObject()->sinterstore(...\func_get_args()); } - public function sunion(mixed $key, mixed ...$other_keys): \Relay\Cluster|array|false + public function sunion(mixed $key, mixed ...$other_keys): Cluster|array|false { return $this->initializeLazyObject()->sunion(...\func_get_args()); } - public function sunionstore(mixed $key, mixed ...$other_keys): \Relay\Cluster|false|int + public function sunionstore(mixed $key, mixed ...$other_keys): Cluster|false|int { return $this->initializeLazyObject()->sunionstore(...\func_get_args()); } @@ -827,12 +827,12 @@ public function sunsubscribe(array $channels = []): bool return $this->initializeLazyObject()->sunsubscribe(...\func_get_args()); } - public function touch(array|string $key_or_array, mixed ...$more_keys): \Relay\Cluster|false|int + public function touch(array|string $key_or_array, mixed ...$more_keys): Cluster|false|int { return $this->initializeLazyObject()->touch(...\func_get_args()); } - public function multi(int $mode = Relay::MULTI): \Relay\Cluster|bool + public function multi(int $mode = Relay::MULTI): Cluster|bool { return $this->initializeLazyObject()->multi(...\func_get_args()); } @@ -842,12 +842,12 @@ public function exec(): array|false return $this->initializeLazyObject()->exec(...\func_get_args()); } - public function watch(mixed $key, mixed ...$other_keys): \Relay\Cluster|bool + public function watch(mixed $key, mixed ...$other_keys): Cluster|bool { return $this->initializeLazyObject()->watch(...\func_get_args()); } - public function unwatch(): \Relay\Cluster|bool + public function unwatch(): Cluster|bool { return $this->initializeLazyObject()->unwatch(...\func_get_args()); } @@ -882,17 +882,17 @@ public function zscan(mixed $key, mixed &$iterator, mixed $match = null, int $co return $this->initializeLazyObject()->zscan($key, $iterator, ...\array_slice(\func_get_args(), 2)); } - public function zscore(mixed $key, mixed $member): \Relay\Cluster|float|false + public function zscore(mixed $key, mixed $member): Cluster|float|false { return $this->initializeLazyObject()->zscore(...\func_get_args()); } - public function keys(mixed $pattern): \Relay\Cluster|array|false + public function keys(mixed $pattern): Cluster|array|false { return $this->initializeLazyObject()->keys(...\func_get_args()); } - public function slowlog(array|string $key_or_address, string $operation, mixed ...$args): \Relay\Cluster|array|bool|int + public function slowlog(array|string $key_or_address, string $operation, mixed ...$args): Cluster|array|bool|int { return $this->initializeLazyObject()->slowlog(...\func_get_args()); } @@ -902,42 +902,42 @@ public function xadd(mixed $key, string $id, array $values, int $maxlen = 0, boo return $this->initializeLazyObject()->xadd(...\func_get_args()); } - public function smembers(mixed $key): \Relay\Cluster|array|false + public function smembers(mixed $key): Cluster|array|false { return $this->initializeLazyObject()->smembers(...\func_get_args()); } - public function sismember(mixed $key, mixed $member): \Relay\Cluster|bool + public function sismember(mixed $key, mixed $member): Cluster|bool { return $this->initializeLazyObject()->sismember(...\func_get_args()); } - public function smismember(mixed $key, mixed ...$members): \Relay\Cluster|array|false + public function smismember(mixed $key, mixed ...$members): Cluster|array|false { return $this->initializeLazyObject()->smismember(...\func_get_args()); } - public function srem(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function srem(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->srem(...\func_get_args()); } - public function sadd(mixed $key, mixed $member, mixed ...$members): \Relay\Cluster|false|int + public function sadd(mixed $key, mixed $member, mixed ...$members): Cluster|false|int { return $this->initializeLazyObject()->sadd(...\func_get_args()); } - public function sort(mixed $key, array $options = []): \Relay\Cluster|array|false|int + public function sort(mixed $key, array $options = []): Cluster|array|false|int { return $this->initializeLazyObject()->sort(...\func_get_args()); } - public function sort_ro(mixed $key, array $options = []): \Relay\Cluster|array|false|int + public function sort_ro(mixed $key, array $options = []): Cluster|array|false|int { return $this->initializeLazyObject()->sort_ro(...\func_get_args()); } - public function smove(mixed $srckey, mixed $dstkey, mixed $member): \Relay\Cluster|bool + public function smove(mixed $srckey, mixed $dstkey, mixed $member): Cluster|bool { return $this->initializeLazyObject()->smove(...\func_get_args()); } @@ -952,7 +952,7 @@ public function srandmember(mixed $key, int $count = 1): mixed return $this->initializeLazyObject()->srandmember(...\func_get_args()); } - public function scard(mixed $key): \Relay\Cluster|false|int + public function scard(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->scard(...\func_get_args()); } @@ -962,37 +962,37 @@ public function script(array|string $key_or_address, string $operation, string . return $this->initializeLazyObject()->script(...\func_get_args()); } - public function strlen(mixed $key): \Relay\Cluster|false|int + public function strlen(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->strlen(...\func_get_args()); } - public function hlen(mixed $key): \Relay\Cluster|false|int + public function hlen(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->hlen(...\func_get_args()); } - public function llen(mixed $key): \Relay\Cluster|false|int + public function llen(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->llen(...\func_get_args()); } - public function xack(mixed $key, string $group, array $ids): \Relay\Cluster|false|int + public function xack(mixed $key, string $group, array $ids): Cluster|false|int { return $this->initializeLazyObject()->xack(...\func_get_args()); } - public function xclaim(mixed $key, string $group, string $consumer, int $min_idle, array $ids, array $options): \Relay\Cluster|array|bool + public function xclaim(mixed $key, string $group, string $consumer, int $min_idle, array $ids, array $options): Cluster|array|bool { return $this->initializeLazyObject()->xclaim(...\func_get_args()); } - public function xautoclaim(mixed $key, string $group, string $consumer, int $min_idle, string $start, int $count = -1, bool $justid = false): \Relay\Cluster|array|bool + public function xautoclaim(mixed $key, string $group, string $consumer, int $min_idle, string $start, int $count = -1, bool $justid = false): Cluster|array|bool { return $this->initializeLazyObject()->xautoclaim(...\func_get_args()); } - public function xlen(mixed $key): \Relay\Cluster|false|int + public function xlen(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->xlen(...\func_get_args()); } @@ -1002,7 +1002,7 @@ public function xgroup(string $operation, mixed $key = null, ?string $group = nu return $this->initializeLazyObject()->xgroup(...\func_get_args()); } - public function xdel(mixed $key, array $ids): \Relay\Cluster|false|int + public function xdel(mixed $key, array $ids): Cluster|false|int { return $this->initializeLazyObject()->xdel(...\func_get_args()); } @@ -1012,32 +1012,32 @@ public function xinfo(string $operation, string|null $arg1 = null, string|null $ return $this->initializeLazyObject()->xinfo(...\func_get_args()); } - public function xpending(mixed $key, string $group, string|null $start = null, string|null $end = null, int $count = -1, string|null $consumer = null, int $idle = 0): \Relay\Cluster|array|false + public function xpending(mixed $key, string $group, string|null $start = null, string|null $end = null, int $count = -1, string|null $consumer = null, int $idle = 0): Cluster|array|false { return $this->initializeLazyObject()->xpending(...\func_get_args()); } - public function xrange(mixed $key, string $start, string $end, int $count = -1): \Relay\Cluster|array|false + public function xrange(mixed $key, string $start, string $end, int $count = -1): Cluster|array|false { return $this->initializeLazyObject()->xrange(...\func_get_args()); } - public function xread(array $streams, int $count = -1, int $block = -1): \Relay\Cluster|array|bool|null + public function xread(array $streams, int $count = -1, int $block = -1): Cluster|array|bool|null { return $this->initializeLazyObject()->xread(...\func_get_args()); } - public function xreadgroup(mixed $key, string $consumer, array $streams, int $count = 1, int $block = 1): \Relay\Cluster|array|bool|null + public function xreadgroup(mixed $key, string $consumer, array $streams, int $count = 1, int $block = 1): Cluster|array|bool|null { return $this->initializeLazyObject()->xreadgroup(...\func_get_args()); } - public function xrevrange(mixed $key, string $end, string $start, int $count = -1): \Relay\Cluster|array|bool + public function xrevrange(mixed $key, string $end, string $start, int $count = -1): Cluster|array|bool { return $this->initializeLazyObject()->xrevrange(...\func_get_args()); } - public function xtrim(mixed $key, string $threshold, bool $approx = false, bool $minid = false, int $limit = -1): \Relay\Cluster|false|int + public function xtrim(mixed $key, string $threshold, bool $approx = false, bool $minid = false, int $limit = -1): Cluster|false|int { return $this->initializeLazyObject()->xtrim(...\func_get_args()); } @@ -1052,22 +1052,22 @@ public function zrandmember(mixed $key, array|null $options = null): mixed return $this->initializeLazyObject()->zrandmember(...\func_get_args()); } - public function zrange(mixed $key, string $start, string $end, mixed $options = null): \Relay\Cluster|array|false + public function zrange(mixed $key, string $start, string $end, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zrange(...\func_get_args()); } - public function zrevrange(mixed $key, int $start, int $end, mixed $options = null): \Relay\Cluster|array|false + public function zrevrange(mixed $key, int $start, int $end, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zrevrange(...\func_get_args()); } - public function zrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|array|false + public function zrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zrangebyscore(...\func_get_args()); } - public function zrevrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|array|false + public function zrevrangebyscore(mixed $key, mixed $start, mixed $end, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zrevrangebyscore(...\func_get_args()); } @@ -1077,7 +1077,7 @@ public function zrevrank(mixed $key, mixed $rank, bool $withscore = false): Clus return $this->initializeLazyObject()->zrevrank(...\func_get_args()); } - public function zrangestore(mixed $dstkey, mixed $srckey, mixed $start, mixed $end, mixed $options = null): \Relay\Cluster|false|int + public function zrangestore(mixed $dstkey, mixed $srckey, mixed $start, mixed $end, mixed $options = null): Cluster|false|int { return $this->initializeLazyObject()->zrangestore(...\func_get_args()); } @@ -1087,102 +1087,102 @@ public function zrank(mixed $key, mixed $rank, bool $withscore = false): Cluster return $this->initializeLazyObject()->zrank(...\func_get_args()); } - public function zrangebylex(mixed $key, mixed $min, mixed $max, int $offset = -1, int $count = -1): \Relay\Cluster|array|false + public function zrangebylex(mixed $key, mixed $min, mixed $max, int $offset = -1, int $count = -1): Cluster|array|false { return $this->initializeLazyObject()->zrangebylex(...\func_get_args()); } - public function zrevrangebylex(mixed $key, mixed $max, mixed $min, int $offset = -1, int $count = -1): \Relay\Cluster|array|false + public function zrevrangebylex(mixed $key, mixed $max, mixed $min, int $offset = -1, int $count = -1): Cluster|array|false { return $this->initializeLazyObject()->zrevrangebylex(...\func_get_args()); } - public function zrem(mixed $key, mixed ...$args): \Relay\Cluster|false|int + public function zrem(mixed $key, mixed ...$args): Cluster|false|int { return $this->initializeLazyObject()->zrem(...\func_get_args()); } - public function zremrangebylex(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + public function zremrangebylex(mixed $key, mixed $min, mixed $max): Cluster|false|int { return $this->initializeLazyObject()->zremrangebylex(...\func_get_args()); } - public function zremrangebyrank(mixed $key, int $start, int $end): \Relay\Cluster|false|int + public function zremrangebyrank(mixed $key, int $start, int $end): Cluster|false|int { return $this->initializeLazyObject()->zremrangebyrank(...\func_get_args()); } - public function zremrangebyscore(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + public function zremrangebyscore(mixed $key, mixed $min, mixed $max): Cluster|false|int { return $this->initializeLazyObject()->zremrangebyscore(...\func_get_args()); } - public function zcard(mixed $key): \Relay\Cluster|false|int + public function zcard(mixed $key): Cluster|false|int { return $this->initializeLazyObject()->zcard(...\func_get_args()); } - public function zcount(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + public function zcount(mixed $key, mixed $min, mixed $max): Cluster|false|int { return $this->initializeLazyObject()->zcount(...\func_get_args()); } - public function zdiff(array $keys, array|null $options = null): \Relay\Cluster|array|false + public function zdiff(array $keys, array|null $options = null): Cluster|array|false { return $this->initializeLazyObject()->zdiff(...\func_get_args()); } - public function zdiffstore(mixed $dstkey, array $keys): \Relay\Cluster|false|int + public function zdiffstore(mixed $dstkey, array $keys): Cluster|false|int { return $this->initializeLazyObject()->zdiffstore(...\func_get_args()); } - public function zincrby(mixed $key, float $score, mixed $member): \Relay\Cluster|false|float + public function zincrby(mixed $key, float $score, mixed $member): Cluster|false|float { return $this->initializeLazyObject()->zincrby(...\func_get_args()); } - public function zlexcount(mixed $key, mixed $min, mixed $max): \Relay\Cluster|false|int + public function zlexcount(mixed $key, mixed $min, mixed $max): Cluster|false|int { return $this->initializeLazyObject()->zlexcount(...\func_get_args()); } - public function zmscore(mixed $key, mixed ...$members): \Relay\Cluster|array|false + public function zmscore(mixed $key, mixed ...$members): Cluster|array|false { return $this->initializeLazyObject()->zmscore(...\func_get_args()); } - public function zinter(array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|array|false + public function zinter(array $keys, array|null $weights = null, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zinter(...\func_get_args()); } - public function zintercard(array $keys, int $limit = -1): \Relay\Cluster|false|int + public function zintercard(array $keys, int $limit = -1): Cluster|false|int { return $this->initializeLazyObject()->zintercard(...\func_get_args()); } - public function zinterstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|false|int + public function zinterstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): Cluster|false|int { return $this->initializeLazyObject()->zinterstore(...\func_get_args()); } - public function zunion(array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|array|false + public function zunion(array $keys, array|null $weights = null, mixed $options = null): Cluster|array|false { return $this->initializeLazyObject()->zunion(...\func_get_args()); } - public function zunionstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): \Relay\Cluster|false|int + public function zunionstore(mixed $dstkey, array $keys, array|null $weights = null, mixed $options = null): Cluster|false|int { return $this->initializeLazyObject()->zunionstore(...\func_get_args()); } - public function zpopmin(mixed $key, int $count = 1): \Relay\Cluster|array|false + public function zpopmin(mixed $key, int $count = 1): Cluster|array|false { return $this->initializeLazyObject()->zpopmin(...\func_get_args()); } - public function zpopmax(mixed $key, int $count = 1): \Relay\Cluster|array|false + public function zpopmax(mixed $key, int $count = 1): Cluster|array|false { return $this->initializeLazyObject()->zpopmax(...\func_get_args()); } @@ -1197,7 +1197,7 @@ public function _masters(): array return $this->initializeLazyObject()->_masters(...\func_get_args()); } - public function copy(mixed $srckey, mixed $dstkey, array|null $options = null): \Relay\Cluster|bool + public function copy(mixed $srckey, mixed $dstkey, array|null $options = null): Cluster|bool { return $this->initializeLazyObject()->copy(...\func_get_args()); } From 9131e3018872d2ebb6fe8a9a4d6631273513d42c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 24 Mar 2025 17:30:13 +0100 Subject: [PATCH 38/44] use Table::addPrimaryKeyConstraint() with Doctrine DBAL 4.3+ --- Adapter/DoctrineDbalAdapter.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Adapter/DoctrineDbalAdapter.php b/Adapter/DoctrineDbalAdapter.php index c69c777c..d67464a4 100644 --- a/Adapter/DoctrineDbalAdapter.php +++ b/Adapter/DoctrineDbalAdapter.php @@ -19,6 +19,9 @@ use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory; +use Doctrine\DBAL\Schema\Name\Identifier; +use Doctrine\DBAL\Schema\Name\UnqualifiedName; +use Doctrine\DBAL\Schema\PrimaryKeyConstraint; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Tools\DsnParser; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -378,6 +381,11 @@ private function addTableToSchema(Schema $schema): void $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]); $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => true, 'notnull' => false]); $table->addColumn($this->timeCol, 'integer', ['unsigned' => true]); - $table->setPrimaryKey([$this->idCol]); + + if (class_exists(PrimaryKeyConstraint::class)) { + $table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted($this->idCol))], true)); + } else { + $table->setPrimaryKey([$this->idCol]); + } } } From 136a3110506bee2e217930c851d48d86ff9f886b Mon Sep 17 00:00:00 2001 From: Dmitry Danilson Date: Mon, 7 Apr 2025 19:18:05 +0700 Subject: [PATCH 39/44] Fix #60160: ChainAdapter accepts CacheItemPoolInterface, so it should work with adapter of CacheItemPoolInterface other than \Symfony\Component\Cache\Adapter\AdapterInterface --- CacheItem.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CacheItem.php b/CacheItem.php index 1a81706d..20af82b7 100644 --- a/CacheItem.php +++ b/CacheItem.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Cache; +use Psr\Cache\CacheItemInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\Exception\LogicException; @@ -30,7 +31,7 @@ final class CacheItem implements ItemInterface protected float|int|null $expiry = null; protected array $metadata = []; protected array $newMetadata = []; - protected ?ItemInterface $innerItem = null; + protected ?CacheItemInterface $innerItem = null; protected ?string $poolHash = null; protected bool $isTaggable = false; From 10730e9abaa92153a8eb33b1d66c7e9bb3474ff8 Mon Sep 17 00:00:00 2001 From: Bastien THOMAS Date: Wed, 2 Apr 2025 17:35:09 +0200 Subject: [PATCH 40/44] bug #60121[Cache] ArrayAdapter serialization exception clean $expiries --- Adapter/ArrayAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adapter/ArrayAdapter.php b/Adapter/ArrayAdapter.php index 660a5264..be12fb29 100644 --- a/Adapter/ArrayAdapter.php +++ b/Adapter/ArrayAdapter.php @@ -312,7 +312,7 @@ private function freeze($value, string $key): string|int|float|bool|array|\UnitE try { $serialized = serialize($value); } catch (\Exception $e) { - unset($this->values[$key], $this->tags[$key]); + unset($this->values[$key], $this->expiries[$key], $this->tags[$key]); $type = get_debug_type($value); $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage()); CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]); From eba02ab07213aa82845f519d497e1476e65c14b0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Apr 2025 21:58:34 +0200 Subject: [PATCH 41/44] Add tests --- Tests/Adapter/ArrayAdapterTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Tests/Adapter/ArrayAdapterTest.php b/Tests/Adapter/ArrayAdapterTest.php index c49cc319..59dc8b4a 100644 --- a/Tests/Adapter/ArrayAdapterTest.php +++ b/Tests/Adapter/ArrayAdapterTest.php @@ -102,4 +102,17 @@ public function testEnum() $this->assertSame(TestEnum::Foo, $cache->getItem('foo')->get()); } + + public function testExpiryCleanupOnError() + { + $cache = new ArrayAdapter(); + + $item = $cache->getItem('foo'); + $this->assertTrue($cache->save($item->set('bar'))); + $this->assertTrue($cache->hasItem('foo')); + + $item->set(static fn () => null); + $this->assertFalse($cache->save($item)); + $this->assertFalse($cache->hasItem('foo')); + } } From d1abcf763a7414f2e572f676f22da7a06c8cd9ee Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Apr 2025 22:08:46 +0200 Subject: [PATCH 42/44] [Cache] Fix invalidating on save failures with Array|ApcuAdapter --- Adapter/ApcuAdapter.php | 17 ++++------------- Adapter/ArrayAdapter.php | 4 +++- Tests/Adapter/AdapterTestCase.php | 17 +++++++++++++++++ Tests/Adapter/ArrayAdapterTest.php | 13 ------------- Tests/Adapter/PhpArrayAdapterTest.php | 1 + 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/Adapter/ApcuAdapter.php b/Adapter/ApcuAdapter.php index 2eddb49a..c64a603c 100644 --- a/Adapter/ApcuAdapter.php +++ b/Adapter/ApcuAdapter.php @@ -101,19 +101,10 @@ protected function doSave(array $values, int $lifetime): array|bool return $failed; } - try { - if (false === $failures = apcu_store($values, null, $lifetime)) { - $failures = $values; - } - - return array_keys($failures); - } catch (\Throwable $e) { - if (1 === \count($values)) { - // Workaround https://github.com/krakjoe/apcu/issues/170 - apcu_delete(array_key_first($values)); - } - - throw $e; + if (false === $failures = apcu_store($values, null, $lifetime)) { + $failures = $values; } + + return array_keys($failures); } } diff --git a/Adapter/ArrayAdapter.php b/Adapter/ArrayAdapter.php index be12fb29..8ebfc448 100644 --- a/Adapter/ArrayAdapter.php +++ b/Adapter/ArrayAdapter.php @@ -312,7 +312,9 @@ private function freeze($value, string $key): string|int|float|bool|array|\UnitE try { $serialized = serialize($value); } catch (\Exception $e) { - unset($this->values[$key], $this->expiries[$key], $this->tags[$key]); + if (!isset($this->expiries[$key])) { + unset($this->values[$key]); + } $type = get_debug_type($value); $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage()); CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]); diff --git a/Tests/Adapter/AdapterTestCase.php b/Tests/Adapter/AdapterTestCase.php index 13afd913..2f77d29c 100644 --- a/Tests/Adapter/AdapterTestCase.php +++ b/Tests/Adapter/AdapterTestCase.php @@ -352,6 +352,23 @@ public function testNumericKeysWorkAfterMemoryLeakPrevention() $this->assertEquals('value-50', $cache->getItem((string) 50)->get()); } + + public function testErrorsDontInvalidate() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(0, __FUNCTION__); + + $item = $cache->getItem('foo'); + $this->assertTrue($cache->save($item->set('bar'))); + $this->assertTrue($cache->hasItem('foo')); + + $item->set(static fn () => null); + $this->assertFalse($cache->save($item)); + $this->assertSame('bar', $cache->getItem('foo')->get()); + } } class NotUnserializable diff --git a/Tests/Adapter/ArrayAdapterTest.php b/Tests/Adapter/ArrayAdapterTest.php index 59dc8b4a..c49cc319 100644 --- a/Tests/Adapter/ArrayAdapterTest.php +++ b/Tests/Adapter/ArrayAdapterTest.php @@ -102,17 +102,4 @@ public function testEnum() $this->assertSame(TestEnum::Foo, $cache->getItem('foo')->get()); } - - public function testExpiryCleanupOnError() - { - $cache = new ArrayAdapter(); - - $item = $cache->getItem('foo'); - $this->assertTrue($cache->save($item->set('bar'))); - $this->assertTrue($cache->hasItem('foo')); - - $item->set(static fn () => null); - $this->assertFalse($cache->save($item)); - $this->assertFalse($cache->hasItem('foo')); - } } diff --git a/Tests/Adapter/PhpArrayAdapterTest.php b/Tests/Adapter/PhpArrayAdapterTest.php index 5bbe4d1d..ada3149d 100644 --- a/Tests/Adapter/PhpArrayAdapterTest.php +++ b/Tests/Adapter/PhpArrayAdapterTest.php @@ -42,6 +42,7 @@ class PhpArrayAdapterTest extends AdapterTestCase 'testSaveDeferredWhenChangingValues' => 'PhpArrayAdapter is read-only.', 'testSaveDeferredOverwrite' => 'PhpArrayAdapter is read-only.', 'testIsHitDeferred' => 'PhpArrayAdapter is read-only.', + 'testErrorsDontInvalidate' => 'PhpArrayAdapter is read-only.', 'testExpiresAt' => 'PhpArrayAdapter does not support expiration.', 'testExpiresAtWithNull' => 'PhpArrayAdapter does not support expiration.', From ab54d0c5c7a96128db73a986de793b56937ace62 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 18 Apr 2025 14:51:48 +0200 Subject: [PATCH 43/44] Don't enable tracing unless the profiler is enabled --- Adapter/TraceableAdapter.php | 37 ++++++++++++++++++++++ Adapter/TraceableTagAwareAdapter.php | 7 ++-- DependencyInjection/CacheCollectorPass.php | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Adapter/TraceableAdapter.php b/Adapter/TraceableAdapter.php index 43628e4c..3e1bf2bf 100644 --- a/Adapter/TraceableAdapter.php +++ b/Adapter/TraceableAdapter.php @@ -34,6 +34,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, NamespacedPo public function __construct( protected AdapterInterface $pool, + protected readonly ?\Closure $disabled = null, ) { } @@ -45,6 +46,9 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array if (!$this->pool instanceof CacheInterface) { throw new BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); } + if ($this->disabled?->__invoke()) { + return $this->pool->get($key, $callback, $beta, $metadata); + } $isHit = true; $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) { @@ -71,6 +75,9 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array public function getItem(mixed $key): CacheItem { + if ($this->disabled?->__invoke()) { + return $this->pool->getItem($key); + } $event = $this->start(__FUNCTION__); try { $item = $this->pool->getItem($key); @@ -88,6 +95,9 @@ public function getItem(mixed $key): CacheItem public function hasItem(mixed $key): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->hasItem($key); + } $event = $this->start(__FUNCTION__); try { return $event->result[$key] = $this->pool->hasItem($key); @@ -98,6 +108,9 @@ public function hasItem(mixed $key): bool public function deleteItem(mixed $key): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->deleteItem($key); + } $event = $this->start(__FUNCTION__); try { return $event->result[$key] = $this->pool->deleteItem($key); @@ -108,6 +121,9 @@ public function deleteItem(mixed $key): bool public function save(CacheItemInterface $item): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->save($item); + } $event = $this->start(__FUNCTION__); try { return $event->result[$item->getKey()] = $this->pool->save($item); @@ -118,6 +134,9 @@ public function save(CacheItemInterface $item): bool public function saveDeferred(CacheItemInterface $item): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->saveDeferred($item); + } $event = $this->start(__FUNCTION__); try { return $event->result[$item->getKey()] = $this->pool->saveDeferred($item); @@ -128,6 +147,9 @@ public function saveDeferred(CacheItemInterface $item): bool public function getItems(array $keys = []): iterable { + if ($this->disabled?->__invoke()) { + return $this->pool->getItems($keys); + } $event = $this->start(__FUNCTION__); try { $result = $this->pool->getItems($keys); @@ -151,6 +173,9 @@ public function getItems(array $keys = []): iterable public function clear(string $prefix = ''): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->clear($prefix); + } $event = $this->start(__FUNCTION__); try { if ($this->pool instanceof AdapterInterface) { @@ -165,6 +190,9 @@ public function clear(string $prefix = ''): bool public function deleteItems(array $keys): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->deleteItems($keys); + } $event = $this->start(__FUNCTION__); $event->result['keys'] = $keys; try { @@ -176,6 +204,9 @@ public function deleteItems(array $keys): bool public function commit(): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->commit(); + } $event = $this->start(__FUNCTION__); try { return $event->result = $this->pool->commit(); @@ -189,6 +220,9 @@ public function prune(): bool if (!$this->pool instanceof PruneableInterface) { return false; } + if ($this->disabled?->__invoke()) { + return $this->pool->prune(); + } $event = $this->start(__FUNCTION__); try { return $event->result = $this->pool->prune(); @@ -208,6 +242,9 @@ public function reset(): void public function delete(string $key): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->deleteItem($key); + } $event = $this->start(__FUNCTION__); try { return $event->result[$key] = $this->pool->deleteItem($key); diff --git a/Adapter/TraceableTagAwareAdapter.php b/Adapter/TraceableTagAwareAdapter.php index c85d199e..bde27c68 100644 --- a/Adapter/TraceableTagAwareAdapter.php +++ b/Adapter/TraceableTagAwareAdapter.php @@ -18,13 +18,16 @@ */ class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface { - public function __construct(TagAwareAdapterInterface $pool) + public function __construct(TagAwareAdapterInterface $pool, ?\Closure $disabled = null) { - parent::__construct($pool); + parent::__construct($pool, $disabled); } public function invalidateTags(array $tags): bool { + if ($this->disabled?->__invoke()) { + return $this->pool->invalidateTags($tags); + } $event = $this->start(__FUNCTION__); try { return $event->result = $this->pool->invalidateTags($tags); diff --git a/DependencyInjection/CacheCollectorPass.php b/DependencyInjection/CacheCollectorPass.php index ed957406..0b8d6aed 100644 --- a/DependencyInjection/CacheCollectorPass.php +++ b/DependencyInjection/CacheCollectorPass.php @@ -52,7 +52,7 @@ private function addToCollector(string $id, string $name, ContainerBuilder $cont if (!$definition->isPublic() || !$definition->isPrivate()) { $recorder->setPublic($definition->isPublic()); } - $recorder->setArguments([new Reference($innerId = $id.'.recorder_inner')]); + $recorder->setArguments([new Reference($innerId = $id.'.recorder_inner'), new Reference('profiler.is_disabled_state_checker', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]); foreach ($definition->getMethodCalls() as [$method, $args]) { if ('setCallbackWrapper' !== $method || !$args[0] instanceof Definition || !($args[0]->getArguments()[2] ?? null) instanceof Definition) { From c4b217b578c11ec764867aa0c73e602c602965de Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 6 May 2025 20:55:03 +0200 Subject: [PATCH 44/44] choose the correctly cased class name for the SQLite platform --- Adapter/DoctrineDbalAdapter.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Adapter/DoctrineDbalAdapter.php b/Adapter/DoctrineDbalAdapter.php index c3a4909e..8e52dfee 100644 --- a/Adapter/DoctrineDbalAdapter.php +++ b/Adapter/DoctrineDbalAdapter.php @@ -359,9 +359,16 @@ private function getPlatformName(): string $platform = $this->conn->getDatabasePlatform(); + if (interface_exists(DBALException::class)) { + // DBAL 4+ + $sqlitePlatformClass = 'Doctrine\DBAL\Platforms\SQLitePlatform'; + } else { + $sqlitePlatformClass = 'Doctrine\DBAL\Platforms\SqlitePlatform'; + } + return $this->platformName = match (true) { $platform instanceof \Doctrine\DBAL\Platforms\AbstractMySQLPlatform => 'mysql', - $platform instanceof \Doctrine\DBAL\Platforms\SqlitePlatform => 'sqlite', + $platform instanceof $sqlitePlatformClass => 'sqlite', $platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform => 'pgsql', $platform instanceof \Doctrine\DBAL\Platforms\OraclePlatform => 'oci', $platform instanceof \Doctrine\DBAL\Platforms\SQLServerPlatform => 'sqlsrv',