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

Switch to master inside executor when pipelining in replication mode.

The actual code to switch to master has been implemented only in the
standard and the fire-and-forget executor classes since it does not
make sense to have it in special executors used exclusively when in
client-side clustering mode.
Daniele Alessandri 13 жил өмнө
parent
commit
dc889be2a2

+ 17 - 0
lib/Predis/Pipeline/FireAndForgetExecutor.php

@@ -12,6 +12,7 @@
 namespace Predis\Pipeline;
 
 use Predis\Connection\ConnectionInterface;
+use Predis\Connection\ReplicationConnectionInterface;
 
 /**
  * Implements a pipeline executor strategy that writes a list of commands to
@@ -21,11 +22,27 @@ use Predis\Connection\ConnectionInterface;
  */
 class FireAndForgetExecutor implements PipelineExecutorInterface
 {
+    /**
+     * Allows the pipeline executor to perform operations on the
+     * connection before starting to execute the commands stored
+     * in the pipeline.
+     *
+     * @param ConnectionInterface Connection instance.
+     */
+    protected function checkConnection(ConnectionInterface $connection)
+    {
+        if ($connection instanceof ReplicationConnectionInterface) {
+            $connection->switchTo('master');
+        }
+    }
+
     /**
      * {@inheritdoc}
      */
     public function execute(ConnectionInterface $connection, &$commands)
     {
+        $this->checkConnection($connection);
+
         foreach ($commands as $command) {
             $connection->writeCommand($command);
         }

+ 0 - 8
lib/Predis/Pipeline/PipelineContext.php

@@ -15,7 +15,6 @@ use Predis\ClientInterface;
 use Predis\BasicClientInterface;
 use Predis\ExecutableContextInterface;
 use Predis\Command\CommandInterface;
-use Predis\Connection\ReplicationConnectionInterface;
 use Predis\Helpers;
 use Predis\ClientException;
 
@@ -123,13 +122,6 @@ class PipelineContext implements BasicClientInterface, ExecutableContextInterfac
         if (count($this->pipeline) > 0) {
             if ($send) {
                 $connection = $this->client->getConnection();
-
-                // TODO: it would be better to use a dedicated pipeline executor
-                //       for classes implementing master/slave replication.
-                if ($connection instanceof ReplicationConnectionInterface) {
-                    $connection->switchTo('master');
-                }
-
                 $replies = $this->executor->execute($connection, $this->pipeline);
                 $this->replies = array_merge($this->replies, $replies);
             }

+ 17 - 0
lib/Predis/Pipeline/StandardExecutor.php

@@ -13,6 +13,7 @@ namespace Predis\Pipeline;
 
 use Predis\ServerException;
 use Predis\Connection\ConnectionInterface;
+use Predis\Connection\ReplicationConnectionInterface;
 
 /**
  * Implements the standard pipeline executor strategy used
@@ -23,6 +24,20 @@ use Predis\Connection\ConnectionInterface;
  */
 class StandardExecutor implements PipelineExecutorInterface
 {
+    /**
+     * Allows the pipeline executor to perform operations on the
+     * connection before starting to execute the commands stored
+     * in the pipeline.
+     *
+     * @param ConnectionInterface Connection instance.
+     */
+    protected function checkConnection(ConnectionInterface $connection)
+    {
+        if ($connection instanceof ReplicationConnectionInterface) {
+            $connection->switchTo('master');
+        }
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -31,6 +46,8 @@ class StandardExecutor implements PipelineExecutorInterface
         $sizeofPipe = count($commands);
         $values = array();
 
+        $this->checkConnection($connection);
+
         foreach ($commands as $command) {
             $connection->writeCommand($command);
         }