Sfoglia il codice sorgente

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 anni fa
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);
         }