20use Psr\Log\LoggerAwareInterface;
21use Psr\Log\LoggerInterface;
93 $this->lastError =
null;
104 public function __call( $name, $arguments ) {
106 $lname = strtolower( $name );
108 ( $lname ===
'blpop' || $lname ===
'brpop' || $lname ===
'brpoplpush' )
109 && count( $arguments ) > 1
112 $timeout = end( $arguments );
114 $this->pool->resetTimeout( $this->conn, ( $timeout > 0 ? $timeout + 1 : $timeout ) );
117 return $this->
tryCall( $name, $arguments );
128 private function tryCall( $method, $arguments ) {
129 $this->conn->clearLastError();
131 $res = $this->conn->$method( ...$arguments );
133 if ( $authError === self::AUTH_ERROR_TEMPORARY ) {
134 $res = $this->conn->$method( ...$arguments );
136 if ( $authError === self::AUTH_ERROR_PERMANENT ) {
137 throw new RedisException(
"Failure reauthenticating to Redis." );
155 public function scan( &$iterator, $pattern =
null, $count =
null ) {
156 return $this->
tryCall(
'scan', [ &$iterator, $pattern, $count ] );
170 public function sScan( $key, &$iterator, $pattern =
null, $count =
null ) {
171 return $this->
tryCall(
'sScan', [ $key, &$iterator, $pattern, $count ] );
185 public function hScan( $key, &$iterator, $pattern =
null, $count =
null ) {
186 return $this->
tryCall(
'hScan', [ $key, &$iterator, $pattern, $count ] );
200 public function zScan( $key, &$iterator, $pattern =
null, $count =
null ) {
201 return $this->
tryCall(
'zScan', [ $key, &$iterator, $pattern, $count ] );
210 if ( preg_match(
'/^ERR operation not permitted\b/', $this->conn->getLastError() ) ) {
211 if ( !$this->pool->reauthenticateConnection( $this->server, $this->conn ) ) {
214 $this->conn->clearLastError();
216 "Used automatic re-authentication for Redis.",
217 [
'redis_server' => $this->server ]
233 $this->pool->resetTimeout( $this->conn );
243 public function luaEval( $script, array $params, $numKeys ) {
244 $sha1 = sha1( $script );
249 $conn->clearLastError();
250 $res =
$conn->evalSha( $sha1, $params, $numKeys );
255 if ( preg_match(
'/^ERR operation not permitted\b/',
$conn->getLastError() ) ) {
256 $this->pool->reauthenticateConnection(
$server,
$conn );
257 $conn->clearLastError();
258 $res =
$conn->eval( $script, $params, $numKeys );
260 "Used automatic re-authentication for Lua script '$sha1'.",
265 if ( preg_match(
'/^NOSCRIPT/',
$conn->getLastError() ) ) {
266 $conn->clearLastError();
267 $res =
$conn->eval( $script, $params, $numKeys );
269 "Used eval() for Lua script '$sha1'.",
274 if (
$conn->getLastError() ) {
275 $this->logger->error(
276 'Lua script error on server "{redis_server}": {lua_error}',
279 'lua_error' =>
$conn->getLastError()
294 return $this->conn ===
$conn;
298 $this->pool->freeConnection( $this->server, $this->conn );
Helper class to handle automatically marking connectons as reusable (via RAII pattern)
RedisConnectionPool $pool
zScan( $key, &$iterator, $pattern=null, $count=null)
Sorted Set Scan Handle this explicity due to needing the iterator passed by reference.
const AUTH_ERROR_PERMANENT
Authentication error was permanent and could not be recovered.
scan(&$iterator, $pattern=null, $count=null)
Key Scan Handle this explicity due to needing the iterator passed by reference.
tryCall( $method, $arguments)
Do the method call in the common try catch handler.
__call( $name, $arguments)
Magic __call handler for most Redis functions.
luaEval( $script, array $params, $numKeys)
sScan( $key, &$iterator, $pattern=null, $count=null)
Set Scan Handle this explicity due to needing the iterator passed by reference.
hScan( $key, &$iterator, $pattern=null, $count=null)
Hash Scan Handle this explicity due to needing the iterator passed by reference.
__construct(RedisConnectionPool $pool, $server, Redis $conn, LoggerInterface $logger)
setLogger(LoggerInterface $logger)
postCallCleanup()
Post Redis call cleanup.
checkAuthentication()
Handle authentication errors and automatically reauthenticate.
const AUTH_ERROR_TEMPORARY
Temporary authentication error; recovered by reauthenticating.
const AUTH_NO_ERROR
No authentication errors.
isConnIdentical(Redis $conn)
Helper class to manage Redis connections.