Merge "(bug 47070) check content model namespace on import."
[lhc/web/wiklou.git] / includes / clientpool / RedisConnectionPool.php
index eb30a1d..8a6718f 100644 (file)
@@ -52,15 +52,15 @@ class RedisConnectionPool {
        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". */
@@ -68,6 +68,7 @@ class RedisConnectionPool {
 
        /**
         * @param array $options
+        * @throws MWException
         */
        protected function __construct( array $options ) {
                if ( !class_exists( 'Redis' ) ) {
@@ -89,8 +90,8 @@ class RedisConnectionPool {
        }
 
        /**
-        * @param $options Array
-        * @return Array
+        * @param array $options
+        * @return array
         */
        protected static function applyDefaultConfig( array $options ) {
                if ( !isset( $options['connectTimeout'] ) ) {
@@ -102,11 +103,12 @@ class RedisConnectionPool {
                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.
@@ -127,6 +129,7 @@ class RedisConnectionPool {
                        self::$instances[$id] = new self( $options );
                        wfDebug( "Creating a new " . __CLASS__ . " instance with id $id." );
                }
+
                return self::$instances[$id];
        }
 
@@ -151,6 +154,7 @@ class RedisConnectionPool {
                                // Server is dead
                                wfDebug( "server $server is marked down for another " .
                                        ( $this->downServers[$server] - $now ) . " seconds, can't get connection" );
+
                                return false;
                        }
                }
@@ -161,6 +165,7 @@ class RedisConnectionPool {
                                if ( $connection['free'] ) {
                                        $connection['free'] = false;
                                        --$this->idlePoolSize;
+
                                        return new RedisConnRef( $this, $server, $connection['conn'] );
                                }
                        }
@@ -195,6 +200,7 @@ class RedisConnectionPool {
                                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 ) {
@@ -204,13 +210,15 @@ class RedisConnectionPool {
                        }
                } 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;
@@ -220,9 +228,9 @@ class RedisConnectionPool {
        /**
         * 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;
@@ -242,15 +250,13 @@ class RedisConnectionPool {
 
        /**
         * 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] );
@@ -268,10 +274,9 @@ class RedisConnectionPool {
         * 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" );
@@ -304,11 +309,24 @@ class RedisConnectionPool {
                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();
+                       }
+               }
+       }
 }
 
 /**
@@ -329,9 +347,9 @@ class RedisConnRef {
        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;
@@ -414,7 +432,7 @@ class RedisConnRef {
        }
 
        /**
-        * @param RedisConnRef $conn
+        * @param Redis $conn
         * @return bool
         */
        public function isConnIdentical( Redis $conn ) {