فهرست منبع

Add new "replication" client option for master / slave replication.

When the "replication" option is specified and evaluates to true, the array of
connection parameters passed to the client constructor os be used to initialize
a new instance of Predis\Network\IConnectionReplication. This option can also
accept a callable object used as an initializer or the fully-qualified name of
a class.
Daniele Alessandri 13 سال پیش
والد
کامیت
6f4347010d

+ 7 - 1
lib/Predis/Client.php

@@ -90,8 +90,14 @@ class Client
         if ($parameters instanceof IConnection) {
             return $parameters;
         }
+
         if (is_array($parameters) && isset($parameters[0])) {
-            return $this->connections->createCluster($this->options->cluster, $parameters, $this->profile);
+            $replication = isset($this->options->replication) && $this->options->replication;
+
+            $connection = $this->options->{$replication ? 'replication' : 'cluster'};
+            $initializer = $replication ? 'createReplication' : 'createCluster';
+
+            return $this->connections->$initializer($connection, $parameters, $this->profile);
         }
 
         return $this->connections->create($parameters, $this->profile);

+ 13 - 0
lib/Predis/ConnectionFactory.php

@@ -14,6 +14,7 @@ namespace Predis;
 use Predis\Profiles\IServerProfile;
 use Predis\Network\IConnectionSingle;
 use Predis\Network\IConnectionCluster;
+use Predis\Network\IConnectionReplication;
 use Predis\Profiles\ServerProfile;
 
 /**
@@ -135,6 +136,18 @@ class ConnectionFactory implements IConnectionFactory
         return $cluster;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function createReplication(IConnectionReplication $replication, $parameters, IServerProfile $profile = null)
+    {
+        foreach ($parameters as $node) {
+            $replication->add($node instanceof IConnectionSingle ? $node : $this->create($node, $profile));
+        }
+
+        return $replication;
+    }
+
     /**
      * Prepares a connection object after its initialization.
      *

+ 10 - 0
lib/Predis/IConnectionFactory.php

@@ -13,6 +13,7 @@ namespace Predis;
 
 use Predis\Profiles\IServerProfile;
 use Predis\Network\IConnectionCluster;
+use Predis\Network\IConnectionReplication;
 
 /**
  * Interface that must be implemented by classes that provide their own mechanism
@@ -53,4 +54,13 @@ interface IConnectionFactory
      * @return Predis\Network\IConnectionCluster
      */
     public function createCluster(IConnectionCluster $cluster, $parameters, IServerProfile $profile = null);
+
+    /**
+     * Prepares a master / slave replication configuration.
+     *
+     * @param IConnectionReplication Instance of a connection cluster class.
+     * @param array $parameters List of parameters for each connection object.
+     * @return Predis\Network\IConnectionReplication
+     */
+    public function createReplication(IConnectionReplication $replication, $parameters, IServerProfile $profile = null);
 }

+ 1 - 0
lib/Predis/Options/ClientOptions.php

@@ -42,6 +42,7 @@ class ClientOptions implements IClientOptions
             'profile' => new ClientProfile(),
             'connections' => new ClientConnectionFactory(),
             'cluster' => new ClientCluster(),
+            'replication' => new ClientReplication(),
             'prefix' => new ClientPrefix(),
         );
     }

+ 74 - 0
lib/Predis/Options/ClientReplication.php

@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Predis package.
+ *
+ * (c) Daniele Alessandri <suppakilla@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Predis\Options;
+
+use Predis\Network\IConnectionReplication;
+use Predis\Network\PredisReplication;
+
+/**
+ * Option class that returns a replication connection be used by a client.
+ *
+ * @author Daniele Alessandri <suppakilla@gmail.com>
+ */
+class ClientReplication extends Option
+{
+    /**
+     * Checks if the specified value is a valid instance of IConnectionReplication.
+     *
+     * @param IConnectionReplication $cluster Instance of a connection cluster.
+     * @return IConnectionReplication
+     */
+    protected function checkInstance($connection)
+    {
+        if (!$connection instanceof IConnectionReplication) {
+            throw new \InvalidArgumentException('Instance of Predis\Network\IConnectionReplication expected');
+        }
+
+        return $connection;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function filter(IClientOptions $options, $value)
+    {
+        if (is_callable($value)) {
+            $connection = call_user_func($value, $options);
+            if (!$connection instanceof IConnectionReplication) {
+                throw new \InvalidArgumentException('Instance of Predis\Network\IConnectionReplication expected');
+            }
+            return $connection;
+        }
+
+        if (is_string($value)) {
+            if (!class_exists($value)) {
+                throw new \InvalidArgumentException("Class $value does not exist");
+            }
+            if (!($connection = new $value()) instanceof IConnectionReplication) {
+                throw new \InvalidArgumentException('Instance of Predis\Network\IConnectionReplication expected');
+            }
+            return $connection;
+        }
+
+        if ($value == true) {
+            return $this->getDefault($options);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDefault(IClientOptions $options)
+    {
+        return new PredisReplication();
+    }
+}