protected $serializer;
/** @} */
- /** @var integer Current idle pool size */
+ /** @var int Current idle pool size */
protected $idlePoolSize = 0;
- /** @var Array (server name => ((connection info array),...) */
+ /** @var array (server name => ((connection info array),...) */
protected $connections = array();
- /** @var Array (server name => UNIX timestamp) */
+ /** @var array (server name => UNIX timestamp) */
protected $downServers = array();
- /** @var Array (pool ID => RedisConnectionPool) */
+ /** @var array (pool ID => RedisConnectionPool) */
protected static $instances = array();
/** integer; seconds to cache servers as "down". */
/**
* @param array $options
+ * @throws MWException
*/
protected function __construct( array $options ) {
if ( !class_exists( 'Redis' ) ) {
}
/**
- * @param $options Array
- * @return Array
+ * @param array $options
+ * @return array
*/
protected static function applyDefaultConfig( array $options ) {
if ( !isset( $options['connectTimeout'] ) ) {
if ( !isset( $options['password'] ) ) {
$options['password'] = null;
}
+
return $options;
}
/**
- * @param $options Array
+ * @param array $options
* $options include:
* - connectTimeout : The timeout for new connections, in seconds.
* Optional, default is 1 second.
self::$instances[$id] = new self( $options );
wfDebug( "Creating a new " . __CLASS__ . " instance with id $id." );
}
+
return self::$instances[$id];
}
// Server is dead
wfDebug( "server $server is marked down for another " .
( $this->downServers[$server] - $now ) . " seconds, can't get connection" );
+
return false;
}
}
if ( $connection['free'] ) {
$connection['free'] = false;
--$this->idlePoolSize;
+
return new RedisConnRef( $this, $server, $connection['conn'] );
}
}
wfDebugLog( 'redis', "Could not connect to 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 ) {
}
} catch ( RedisException $e ) {
$this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
- wfDebugLog( 'redis', "Redis exception: " . $e->getMessage() . "\n" );
+ wfDebugLog( 'redis', "Redis exception connecting to $server: " . $e->getMessage() . "\n" );
+
return false;
}
if ( $conn ) {
$conn->setOption( Redis::OPT_SERIALIZER, $this->serializer );
$this->connections[$server][] = array( 'conn' => $conn, 'free' => false );
+
return new RedisConnRef( $this, $server, $conn );
} else {
return false;
/**
* Mark a connection to a server as free to return to the pool
*
- * @param $server string
- * @param $conn Redis
- * @return boolean
+ * @param string $server
+ * @param Redis $conn
+ * @return bool
*/
public function freeConnection( $server, Redis $conn ) {
$found = false;
/**
* Close any extra idle connections if there are more than the limit
- *
- * @return void
*/
protected function closeExcessIdleConections() {
if ( $this->idlePoolSize <= count( $this->connections ) ) {
return; // nothing to do (no more connections than servers)
}
- foreach ( $this->connections as $server => &$serverConnections ) {
+ foreach ( $this->connections as &$serverConnections ) {
foreach ( $serverConnections as $key => &$connection ) {
if ( $connection['free'] ) {
unset( $serverConnections[$key] );
* not. The safest response for us is to explicitly destroy the connection
* object and let it be reopened during the next request.
*
- * @param $server string
- * @param $cref RedisConnRef
- * @param $e RedisException
- * @return void
+ * @param string $server
+ * @param RedisConnRef $cref
+ * @param RedisException $e
*/
public function handleException( $server, RedisConnRef $cref, RedisException $e ) {
wfDebugLog( 'redis', "Redis exception on server $server: " . $e->getMessage() . "\n" );
if ( $this->password !== null ) {
if ( !$conn->auth( $this->password ) ) {
wfDebugLog( 'redis', "Authentication error connecting to $server" );
+
return false;
}
}
+
return true;
}
+
+ /**
+ * Make sure connections are closed for sanity
+ */
+ function __destruct() {
+ foreach ( $this->connections as $server => &$serverConnections ) {
+ foreach ( $serverConnections as $key => &$connection ) {
+ $connection['conn']->close();
+ }
+ }
+ }
}
/**
protected $lastError; // string
/**
- * @param $pool RedisConnectionPool
- * @param $server string
- * @param $conn Redis
+ * @param RedisConnectionPool $pool
+ * @param string $server
+ * @param Redis $conn
*/
public function __construct( RedisConnectionPool $pool, $server, Redis $conn ) {
$this->pool = $pool;
}
/**
- * @param RedisConnRef $conn
+ * @param Redis $conn
* @return bool
*/
public function isConnIdentical( Redis $conn ) {