瀏覽代碼

Fix ROLE expectation for read commands with no slaves.

This commit fixes #337.
Daniele Alessandri 9 年之前
父節點
當前提交
0477499418

+ 5 - 5
src/Connection/Aggregate/SentinelReplication.php

@@ -535,11 +535,11 @@ class SentinelReplication implements ReplicationInterface
     {
         $connection = $this->getConnectionInternal($command);
 
-        if (!$connection->isConnected() && ($this->slaves || $this->master)) {
-            $this->assertConnectionRole(
-                $connection,
-                $this->strategy->isReadOperation($command) ? 'slave' : 'master'
-            );
+        if (!$connection->isConnected()) {
+            // When we do not have any available slave in the pool we can expect
+            // read-only operations to hit the master server.
+            $expectedRole = $this->strategy->isReadOperation($command) && $this->slaves ? 'slave' : 'master';
+            $this->assertConnectionRole($connection, $expectedRole);
         }
 
         return $connection;

+ 43 - 0
tests/Predis/Connection/Aggregate/SentinelReplicationTest.php

@@ -795,6 +795,49 @@ class SentinelReplicationTest extends PredisTestCase
         $replication->getConnection(Command\RawCommand::create('del', 'key'));
     }
 
+    /**
+     * @group disconnected
+     */
+    public function testGetConnectionReturnsMasterForReadOnlyOperationsOnUnavailableSlaves()
+    {
+        $sentinel1 = $this->getMockSentinelConnection('tcp://127.0.0.1:5381?alias=sentinel1');
+        $sentinel1->expects($this->once())
+                  ->method('executeCommand')
+                  ->with($this->isRedisCommand(
+                      'SENTINEL', array('slaves', 'svc')
+                  ))
+                  ->will($this->returnValue(
+                      array(
+                          array(
+                              'name', '127.0.0.1:6382',
+                              'ip', '127.0.0.1',
+                              'port', '6382',
+                              'runid', '1c0bf1291797fbc5608c07a17da394147dc62817',
+                              'flags', 'slave,s_down,disconnected',
+                              'master-host', '127.0.0.1',
+                              'master-port', '6381',
+                          ),
+                      )
+                  ));
+
+        $master = $this->getMockConnection('tcp://127.0.0.1:6381?alias=master');
+        $master->expects($this->once())
+               ->method('isConnected')
+               ->will($this->returnValue(false));
+        $master->expects($this->at(2))
+               ->method('executeCommand')
+               ->with($this->isRedisCommand('ROLE'))
+               ->will($this->returnValue(array(
+                   'master', '0', array(),
+               )));
+
+        $replication = $this->getReplicationConnection('svc', array($sentinel1));
+
+        $replication->add($master);
+
+        $replication->getConnection(Command\RawCommand::create('get', 'key'));
+    }
+
     /**
      * @group disconnected
      */