From ea86cbb224253efce9951ff37673f6aa0170f990 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Tue, 5 Nov 2013 14:43:49 -0800 Subject: [PATCH] Fixed redis reconnect handling when passwords are used in luaEval() Change-Id: Ifc974e6787d180f9b14624481ffe7c456f689254 --- includes/clientpool/RedisConnectionPool.php | 31 ++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/includes/clientpool/RedisConnectionPool.php b/includes/clientpool/RedisConnectionPool.php index f7653eb2a6..c8e98a7d52 100644 --- a/includes/clientpool/RedisConnectionPool.php +++ b/includes/clientpool/RedisConnectionPool.php @@ -283,6 +283,25 @@ class RedisConnectionPool { } } } + + /** + * Resend an AUTH request to the redis server (useful after disconnects) + * + * This method is for internal use only + * + * @param string $server + * @param Redis $conn + * @return bool Success + */ + public function reauthenticateConnection( $server, Redis $conn ) { + if ( $this->password !== null ) { + if ( !$conn->auth( $this->password ) ) { + wfDebugLog( 'redis', "Authentication error connecting to $server" ); + return false; + } + } + return true; + } } /** @@ -324,10 +343,21 @@ class RedisConnRef { public function luaEval( $script, array $params, $numKeys ) { $sha1 = sha1( $script ); // 40 char hex $conn = $this->conn; // convenience + $server = $this->server; // convenience // Try to run the server-side cached copy of the script $conn->clearLastError(); $res = $conn->evalSha( $sha1, $params, $numKeys ); + // If we got a permission error reply that means that (a) we are not in + // multi()/pipeline() and (b) some connection problem likely occured. If + // the password the client gave was just wrong, an exception should have + // been thrown back in getConnection() previously. + if ( preg_match( '/^ERR operation not permitted\b/', $conn->getLastError() ) ) { + $this->pool->reauthenticateConnection( $server, $conn ); + $conn->clearLastError(); + $res = $conn->eval( $script, $params, $numKeys ); + wfDebugLog( 'redis', "Used automatic re-authentication for Lua script $sha1." ); + } // If the script is not in cache, use eval() to retry and cache it if ( preg_match( '/^NOSCRIPT/', $conn->getLastError() ) ) { $conn->clearLastError(); @@ -336,7 +366,6 @@ class RedisConnRef { } if ( $conn->getLastError() ) { // script bug? - $server = $this->server; wfDebugLog( 'redis', "Lua script error on server $server: " . $conn->getLastError() ); } -- 2.20.1