Эх сурвалжийг харах

Use master for connect() on empty slaves pool.

Internally the replication class uses this order to pick which server
it should connect to: current connection, one of the slaves, master.

If there is at least 1 slave, connect() will not fail even if master
is undefined. If there are no slaves, connect() will pick master. If
there are no connections registered for replication, connect() will
fail immediatly.
Daniele Alessandri 9 жил өмнө
parent
commit
5b76b41fda

+ 6 - 15
src/Connection/Aggregate/MasterSlaveReplication.php

@@ -53,16 +53,6 @@ class MasterSlaveReplication implements ReplicationInterface
         $this->strategy = $strategy ?: new ReplicationStrategy();
     }
 
-    /**
-     * Checks if one master and at least one slave have been defined.
-     */
-    protected function check()
-    {
-        if (!isset($this->master) || !$this->slaves) {
-            throw new \RuntimeException('Replication needs one master and at least one slave.');
-        }
-    }
-
     /**
      * Resets the connection state.
      */
@@ -156,8 +146,6 @@ class MasterSlaveReplication implements ReplicationInterface
      */
     public function switchTo($connection)
     {
-        $this->check();
-
         if (!$connection instanceof NodeConnectionInterface) {
             $connection = $this->getConnectionById($connection);
         }
@@ -242,9 +230,12 @@ class MasterSlaveReplication implements ReplicationInterface
      */
     public function connect()
     {
-        if ($this->current === null) {
-            $this->check();
-            $this->current = $this->pickSlave();
+        if (!$this->current) {
+            if (!$this->current = $this->pickSlave()) {
+                if (!$this->current = $this->getMaster()) {
+                    throw new ClientException("No available connection for replication");
+                }
+            }
         }
 
         $this->current->connect();

+ 11 - 23
tests/Predis/Connection/Aggregate/MasterSlaveReplicationTest.php

@@ -65,8 +65,8 @@ class MasterSlaveReplicationTest extends PredisTestCase
 
     /**
      * @group disconnected
-     * @expectedException \RuntimeException
-     * @expectedExceptionMessage Replication needs one master and at least one slave.
+     * @expectedException \Predis\ClientException
+     * @expectedExceptionMessage No available connection for replication
      */
     public function testThrowsExceptionOnEmptyReplication()
     {
@@ -76,26 +76,18 @@ class MasterSlaveReplicationTest extends PredisTestCase
 
     /**
      * @group disconnected
-     * @expectedException \RuntimeException
-     * @expectedExceptionMessage Replication needs one master and at least one slave.
      */
-    public function testThrowsExceptionOnMissingMaster()
+    public function testConnectsToOneOfSlaves()
     {
-        $replication = new MasterSlaveReplication();
-        $replication->add($this->getMockConnection('tcp://host2?alias=slave1'));
+        $master = $this->getMockConnection('tcp://host1?alias=master');
+        $master->expects($this->never())->method('connect');
 
-        $replication->connect();
-    }
+        $slave = $this->getMockConnection('tcp://host2?alias=slave1');
+        $slave->expects($this->once())->method('connect');
 
-    /**
-     * @group disconnected
-     * @expectedException \RuntimeException
-     * @expectedExceptionMessage Replication needs one master and at least one slave.
-     */
-    public function testThrowsExceptionOnMissingSlave()
-    {
         $replication = new MasterSlaveReplication();
-        $replication->add($this->getMockConnection('tcp://host1?alias=master'));
+        $replication->add($master);
+        $replication->add($slave);
 
         $replication->connect();
     }
@@ -103,19 +95,15 @@ class MasterSlaveReplicationTest extends PredisTestCase
     /**
      * @group disconnected
      */
-    public function testConnectForcesConnectionToOneOfSlaves()
+    public function testConnectsToMasterOnMissingSlaves()
     {
         $master = $this->getMockConnection('tcp://host1?alias=master');
-        $master->expects($this->never())->method('connect');
-
-        $slave = $this->getMockConnection('tcp://host2?alias=slave1');
-        $slave->expects($this->once())->method('connect');
 
         $replication = new MasterSlaveReplication();
         $replication->add($master);
-        $replication->add($slave);
 
         $replication->connect();
+        $this->assertSame($master, $replication->getCurrent());
     }
 
     /**