Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
For MediaWiki 1.36, add support for setting reddis database from the config file.
// 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