Bladeren bron

Make it possible to remove connections from a cluster.

Daniele Alessandri 13 jaren geleden
bovenliggende
commit
25b7d72fc9

+ 8 - 0
lib/Predis/Network/IConnectionCluster.php

@@ -28,6 +28,14 @@ interface IConnectionCluster extends IConnection
      */
     public function add(IConnectionSingle $connection);
 
+    /**
+     * Removes the specified connection instance from the cluster.
+     *
+     * @param IConnectionSingle $connection Instance of a connection.
+     * @return Boolean Returns true if the connection was in the pool.
+     */
+    public function remove(IConnectionSingle $connection);
+
     /**
      * Gets the actual connection instance in charge of the specified command.
      *

+ 39 - 1
lib/Predis/Network/PredisCluster.php

@@ -25,7 +25,7 @@ use Predis\Distribution\HashRing;
  * @author Daniele Alessandri <suppakilla@gmail.com>
  * @todo Add the ability to remove connections from pool.
  */
-class PredisCluster implements IConnectionCluster, \IteratorAggregate
+class PredisCluster implements IConnectionCluster, \IteratorAggregate, \Countable
 {
     private $pool;
     private $distributor;
@@ -91,6 +91,36 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate
         $this->distributor->add($connection, $weight);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function remove(IConnectionSingle $connection)
+    {
+        if (($id = array_search($connection, $this->pool, true)) !== false) {
+            unset($this->pool[$id]);
+            $this->distributor->remove($connection);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Removes a connection instance using its alias or index.
+     *
+     * @param string $connectionId Alias or index of a connection.
+     * @return Boolean Returns true if the connection was in the pool.
+     */
+    public function removeById($connectionId)
+    {
+        if ($connection = $this->getConnectionById($connectionId)) {
+            return $this->remove($connection);
+        }
+
+        return false;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -131,6 +161,14 @@ class PredisCluster implements IConnectionCluster, \IteratorAggregate
         return $this->distributor->get($keyHash);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function count()
+    {
+        return count($this->pool);
+    }
+
     /**
      * {@inheritdoc}
      */

+ 41 - 0
tests/Predis/Network/PredisClusterTest.php

@@ -33,6 +33,7 @@ class PredisClusterTest extends StandardTestCase
         $cluster->add($connection1);
         $cluster->add($connection2);
 
+        $this->assertSame(2, count($cluster));
         $this->assertSame($connection1, $cluster->getConnectionById(0));
         $this->assertSame($connection2, $cluster->getConnectionById(1));
     }
@@ -49,10 +50,50 @@ class PredisClusterTest extends StandardTestCase
         $cluster->add($connection1);
         $cluster->add($connection2);
 
+        $this->assertSame(2, count($cluster));
         $this->assertSame($connection1, $cluster->getConnectionById('node1'));
         $this->assertSame($connection2, $cluster->getConnectionById('node2'));
     }
 
+    /**
+     * @group disconnected
+     */
+    public function testRemovingConnectionsFromCluster()
+    {
+        $connection1 = $this->getMockConnection();
+        $connection2 = $this->getMockConnection();
+        $connection3 = $this->getMockConnection();
+
+        $cluster = new PredisCluster();
+        $cluster->add($connection1);
+        $cluster->add($connection2);
+
+        $this->assertTrue($cluster->remove($connection1));
+        $this->assertFalse($cluster->remove($connection3));
+        $this->assertSame(1, count($cluster));
+    }
+
+    /**
+     * @group disconnected
+     */
+    public function testRemovingConnectionsFromClusterByAlias()
+    {
+        $connection1 = $this->getMockConnection();
+        $connection2 = $this->getMockConnection('tcp://host1:7001?alias=node2');
+        $connection3 = $this->getMockConnection('tcp://host1:7002?alias=node3');
+        $connection4 = $this->getMockConnection('tcp://host1:7003?alias=node4');
+
+        $cluster = new PredisCluster();
+        $cluster->add($connection1);
+        $cluster->add($connection2);
+        $cluster->add($connection3);
+
+        $this->assertTrue($cluster->removeById(0));
+        $this->assertTrue($cluster->removeById('node2'));
+        $this->assertFalse($cluster->removeById('node4'));
+        $this->assertSame(1, count($cluster));
+    }
+
     /**
      * @group disconnected
      */