Created
October 11, 2021 18:56
-
-
Save yombo/28a0c4747d8b2f11a289429237610747 to your computer and use it in GitHub Desktop.
For MediaWiki 1.36, add support for setting reddis database from the config file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mediawiki/includes/libs/redis/RedisConnectionPool.php | |
// See https://www.mediawiki.org/wiki/Topic:Wi89pk2optfhl3fz | |
/** | |
* Get a connection to a redis server. Based on code in RedisBagOStuff.php. | |
* | |
* @param string $server A hostname/port combination or the absolute path of a UNIX socket. | |
* If a hostname is specified but no port, port 6379 will be used. | |
* @param LoggerInterface|null $logger PSR-3 logger intance. [optional] | |
* @return RedisConnRef|Redis|bool Returns false on failure | |
* @throws InvalidArgumentException | |
*/ | |
public function getConnection( $server, LoggerInterface $logger = null ) { | |
global $wgRedisDatabase; | |
if (is_null($wgRedisDatabase)) { | |
$wgRedisDatabase = 0; | |
} | |
// The above @return also documents 'Redis' for convenience with IDEs. | |
// RedisConnRef uses PHP magic methods, which wouldn't be recognised. | |
$logger = $logger ?: $this->logger; | |
// Check the listing "dead" servers which have had a connection errors. | |
// Servers are marked dead for a limited period of time, to | |
// avoid excessive overhead from repeated connection timeouts. | |
if ( isset( $this->downServers[$server] ) ) { | |
$now = time(); | |
if ( $now > $this->downServers[$server] ) { | |
// Dead time expired | |
unset( $this->downServers[$server] ); | |
} else { | |
// Server is dead | |
$logger->debug( | |
'Server "{redis_server}" is marked down for another ' . | |
( $this->downServers[$server] - $now ) . 'seconds', | |
[ 'redis_server' => $server ] | |
); | |
return false; | |
} | |
} | |
// Check if a connection is already free for use | |
if ( isset( $this->connections[$server] ) ) { | |
foreach ( $this->connections[$server] as &$connection ) { | |
if ( $connection['free'] ) { | |
$connection['free'] = false; | |
--$this->idlePoolSize; | |
return new RedisConnRef( | |
$this, $server, $connection['conn'], $logger | |
); | |
} | |
} | |
} | |
if ( !$server ) { | |
throw new InvalidArgumentException( | |
__CLASS__ . ": invalid configured server \"$server\"" ); | |
} elseif ( substr( $server, 0, 1 ) === '/' ) { | |
// UNIX domain socket | |
// These are required by the redis extension to start with a slash, but | |
// we still need to set the port to a special value to make it work. | |
$host = $server; | |
$port = 0; | |
} else { | |
// TCP connection | |
if ( preg_match( '/^\[(.+)\]:(\d+)$/', $server, $m ) ) { | |
list( $host, $port ) = [ $m[1], (int)$m[2] ]; // (ip, port) | |
} elseif ( preg_match( '/^([^:]+):(\d+)$/', $server, $m ) ) { | |
list( $host, $port ) = [ $m[1], (int)$m[2] ]; // (ip or path, port) | |
} else { | |
list( $host, $port ) = [ $server, 6379 ]; // (ip or path, port) | |
} | |
} | |
$conn = new Redis(); | |
try { | |
if ( $this->persistent ) { | |
$result = $conn->pconnect( $host, $port, $this->connectTimeout, $this->id ); | |
} else { | |
$result = $conn->connect( $host, $port, $this->connectTimeout ); | |
} | |
if ( !$result ) { | |
$logger->error( | |
'Could not connect to server "{redis_server}"', | |
[ 'redis_server' => $server ] | |
); | |
// Mark server down for some time to avoid further timeouts | |
$this->downServers[$server] = time() + self::SERVER_DOWN_TTL; | |
return false; | |
} | |
if ( ( $this->password !== null ) && !$conn->auth( $this->password ) ) { | |
$logger->error( | |
'Authentication error connecting to "{redis_server}"', | |
[ 'redis_server' => $server ] | |
); | |
} | |
} catch ( RedisException $e ) { | |
$this->downServers[$server] = time() + self::SERVER_DOWN_TTL; | |
$logger->error( | |
'Redis exception connecting to "{redis_server}"', | |
[ | |
'redis_server' => $server, | |
'exception' => $e, | |
] | |
); | |
return false; | |
} | |
$conn->select($wgRedisDatabase); | |
$conn->setOption( Redis::OPT_READ_TIMEOUT, $this->readTimeout ); | |
$conn->setOption( Redis::OPT_SERIALIZER, $this->serializer ); | |
$this->connections[$server][] = [ 'conn' => $conn, 'free' => false ]; | |
return new RedisConnRef( $this, $server, $conn, $logger ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment