Browse Source

Use master for read requests on empty slaves pool.

This is the last resort in case all of the slaves are unreachable.
Daniele Alessandri 9 years ago
parent
commit
774b4014d9

+ 10 - 9
src/Connection/Aggregate/MasterSlaveReplication.php

@@ -112,21 +112,22 @@ class MasterSlaveReplication implements ReplicationInterface
      */
      */
     public function getConnection(CommandInterface $command)
     public function getConnection(CommandInterface $command)
     {
     {
-        if ($this->current === null) {
-            $this->check();
-            $this->current = $this->strategy->isReadOperation($command)
-                ? $this->pickSlave()
-                : $this->master;
+        if (!$this->current) {
+            if ($this->strategy->isReadOperation($command) && $slave = $this->pickSlave()) {
+                $this->current = $slave;
+            } else {
+                $this->current = $this->getMaster();
+            }
 
 
             return $this->current;
             return $this->current;
         }
         }
 
 
-        if ($this->current === $this->master) {
-            return $this->current;
+        if ($this->current === $master = $this->getMaster()) {
+            return $master;
         }
         }
 
 
-        if (!$this->strategy->isReadOperation($command)) {
-            $this->current = $this->master;
+        if (!$this->strategy->isReadOperation($command) || !$this->slaves) {
+            $this->current = $master;
         }
         }
 
 
         return $this->current;
         return $this->current;

+ 19 - 0
tests/Predis/Connection/Aggregate/MasterSlaveReplicationTest.php

@@ -254,6 +254,25 @@ class MasterSlaveReplicationTest extends PredisTestCase
         $this->assertSame($master, $replication->getConnection($cmd));
         $this->assertSame($master, $replication->getConnection($cmd));
     }
     }
 
 
+    /**
+     * @group disconnected
+     */
+    public function testUsesMasterOnReadRequestsWhenNoSlavesAvailable()
+    {
+        $profile = Profile\Factory::getDefault();
+
+        $master = $this->getMockConnection('tcp://host1?alias=master');
+
+        $replication = new MasterSlaveReplication();
+        $replication->add($master);
+
+        $cmd = $profile->createCommand('exists', array('foo'));
+        $this->assertSame($master, $replication->getConnection($cmd));
+
+        $cmd = $profile->createCommand('set', array('foo', 'bar'));
+        $this->assertSame($master, $replication->getConnection($cmd));
+    }
+
     /**
     /**
      * @group disconnected
      * @group disconnected
      */
      */