X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fobjectcache%2FRedisBagOStuff.php;h=a9af9b126b9a0e171cdade07690d594ae5e21894;hp=ed0aaa23684f747d6ab593682b191eaad95fd631;hb=59ebff658ce912c1b0e7ef8d8f9bfec5a4e17b39;hpb=3d2a18c4f5e5bb84e04616a3ecd8f422647cf915 diff --git a/includes/objectcache/RedisBagOStuff.php b/includes/objectcache/RedisBagOStuff.php index ed0aaa2368..a9af9b126b 100644 --- a/includes/objectcache/RedisBagOStuff.php +++ b/includes/objectcache/RedisBagOStuff.php @@ -80,7 +80,7 @@ class RedisBagOStuff extends BagOStuff { } } - public function get( $key, &$casToken = null ) { + public function get( $key, &$casToken = null, $flags = 0 ) { list( $server, $conn ) = $this->getConnection( $key ); if ( !$conn ) { @@ -174,7 +174,7 @@ class RedisBagOStuff extends BagOStuff { return $result; } - public function getMulti( array $keys ) { + public function getMulti( array $keys, $flags = 0 ) { $batches = array(); $conns = array(); @@ -372,12 +372,33 @@ class RedisBagOStuff extends BagOStuff { } } - foreach ( $candidates as $tag ) { + while ( ( $tag = array_shift( $candidates ) ) !== null ) { $server = $this->serverTagMap[$tag]; $conn = $this->redisPool->getConnection( $server ); - if ( $conn ) { - return array( $server, $conn ); + if ( !$conn ) { + continue; + } + + // If automatic failover is enabled, check that the server's link + // to its master (if any) is up -- but only if there are other + // viable candidates left to consider. + if ( $this->automaticFailover && $candidates ) { + try { + if ( $this->getMasterLinkStatus( $conn ) === 'down' ) { + // If the master cannot be reached, fail-over to the next server. + // If masters are in data-center A, and slaves in data-center B, + // this helps avoid the case were fail-over happens in A but not + // to the corresponding server in B (e.g. read/write mismatch). + continue; + } + } catch ( RedisException $e ) { + // Server is not accepting commands + $this->handleException( $conn, $e ); + continue; + } } + + return array( $server, $conn ); } $this->setLastError( BagOStuff::ERR_UNREACHABLE ); @@ -385,6 +406,19 @@ class RedisBagOStuff extends BagOStuff { return array( false, false ); } + /** + * Check the master link status of a Redis server that is configured as a slave. + * @param RedisConnRef $conn + * @return string|null Master link status (either 'up' or 'down'), or null + * if the server is not a slave. + */ + protected function getMasterLinkStatus( RedisConnRef $conn ) { + $info = $conn->info(); + return isset( $info['master_link_status'] ) + ? $info['master_link_status'] + : null; + } + /** * Log a fatal error * @param string $msg