20use Psr\Log\LoggerAwareInterface;
21use Psr\Log\LoggerInterface;
49 private const AUTH_NO_ERROR = 200;
54 private const AUTH_ERROR_TEMPORARY = 201;
59 private const AUTH_ERROR_PERMANENT = 202;
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 );
132 $authError = $this->checkAuthentication();
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." );
141 $this->postCallCleanup();
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 ] );
209 private function checkAuthentication() {
212 if ( !$this->pool->reauthenticateConnection( $this->server, $this->conn ) ) {
213 return self::AUTH_ERROR_PERMANENT;
215 $this->conn->clearLastError();
217 "Used automatic re-authentication for Redis.",
218 [
'redis_server' => $this->server ]
220 return self::AUTH_ERROR_TEMPORARY;
222 return self::AUTH_NO_ERROR;
230 private function postCallCleanup() {
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 );
258 $this->pool->reauthenticateConnection(
$server,
$conn );
259 $conn->clearLastError();
260 $res =
$conn->eval( $script, $params, $numKeys );
262 "Used automatic re-authentication for Lua script '$sha1'.",
269 $conn->clearLastError();
270 $res =
$conn->eval( $script, $params, $numKeys );
272 "Used eval() for Lua script '$sha1'.",
279 $this->logger->error(
280 'Lua script error on server "{redis_server}": {lua_error}',
297 return $this->conn ===
$conn;
301 $this->pool->freeConnection( $this->server, $this->conn );
Helper class to handle automatically marking connections as reusable (via RAII pattern)
RedisConnectionPool $pool
zScan( $key, &$iterator, $pattern=null, $count=null)
Sorted Set Scan Handle this explicitly due to needing the iterator passed by reference.
scan(&$iterator, $pattern=null, $count=null)
Key Scan Handle this explicitly due to needing the iterator passed by reference.
__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 explicitly due to needing the iterator passed by reference.
hScan( $key, &$iterator, $pattern=null, $count=null)
Hash Scan Handle this explicitly due to needing the iterator passed by reference.
__construct(RedisConnectionPool $pool, $server, Redis $conn, LoggerInterface $logger)
setLogger(LoggerInterface $logger)
isConnIdentical(Redis $conn)
Helper class to manage Redis connections.