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." );
156 public function scan( &$iterator, $pattern =
null, $count =
null ) {
157 return $this->
tryCall(
'scan', [ &$iterator, $pattern, $count ] );
171 public function sScan( $key, &$iterator, $pattern =
null, $count =
null ) {
172 return $this->
tryCall(
'sScan', [ $key, &$iterator, $pattern, $count ] );
186 public function hScan( $key, &$iterator, $pattern =
null, $count =
null ) {
187 return $this->
tryCall(
'hScan', [ $key, &$iterator, $pattern, $count ] );
201 public function zScan( $key, &$iterator, $pattern =
null, $count =
null ) {
202 return $this->
tryCall(
'zScan', [ $key, &$iterator, $pattern, $count ] );
211 if ( preg_match(
'/^ERR operation not permitted\b/', $this->conn->getLastError() ) ) {
212 if ( !$this->pool->reauthenticateConnection( $this->server, $this->conn ) ) {
215 $this->conn->clearLastError();
217 "Used automatic re-authentication for Redis.",
218 [
'redis_server' => $this->server ]
234 $this->pool->resetTimeout( $this->conn );
244 public function luaEval( $script, array $params, $numKeys ) {
245 $sha1 = sha1( $script );
250 $conn->clearLastError();
251 $res =
$conn->evalSha( $sha1, $params, $numKeys );
256 if ( preg_match(
'/^ERR operation not permitted\b/',
$conn->getLastError() ) ) {
257 $this->pool->reauthenticateConnection(
$server,
$conn );
258 $conn->clearLastError();
259 $res =
$conn->eval( $script, $params, $numKeys );
261 "Used automatic re-authentication for Lua script '$sha1'.",
266 if ( preg_match(
'/^NOSCRIPT/',
$conn->getLastError() ) ) {
267 $conn->clearLastError();
268 $res =
$conn->eval( $script, $params, $numKeys );
270 "Used eval() for Lua script '$sha1'.",
275 if (
$conn->getLastError() ) {
276 $this->logger->error(
277 'Lua script error on server "{redis_server}": {lua_error}',
280 'lua_error' =>
$conn->getLastError()
295 return $this->conn ===
$conn;
299 $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.