Skip to content
Browse files

Redesign how Predis\ConnectionFactory works and make more sense out o…

…f it.
  • Loading branch information...
1 parent 058e112 commit 728afe7fcbe5612c868f4cd8ff066f0c8b97a2e0 @nrk committed Nov 29, 2011
View
4 FAQ.PERFORMANCES.md
@@ -55,7 +55,9 @@ name) and let Predis using it. __phpiredis__ is a C-based extension that wraps _
official Redis C client library) with a thin layer that exposes its features to PHP. You will now
get the benefits of a faster protocol parser just by adding a single line of code in your application:
- Predis\ConnectionFactory::define('tcp', '\Predis\Network\PhpiredisConnection');
+ $client = new Predis\Client('tcp://127.0.0.1', array(
+ 'connections' => array('tcp' => 'Predis\Network\PhpiredisConnection')
+ ));
As simple as it is, nothing will really change in the way you use the library in your application. So,
how fast is it now? There are not much improvements for inline or short bulk replies (e.g. _SET_ or
View
7 README.md
@@ -113,11 +113,12 @@ class MyConnectionClass implements Predis\Network\IConnectionSingle
// implementation goes here
}
-// Let Predis automatically use your own class to handle the default TCP connection
-Predis\ConnectionFactory::define('tcp', 'MyConnectionClass');
+// Let Predis automatically use your own class to handle connections identified by the tcp prefix.
+$client = new Predis\Client('tcp://127.0.0.1', array(
+ 'connections' => array('tcp' => 'MyConnectionClass')
+));
```
-
You can have a look at the `Predis\Network` namespace for some actual code that gives a better
insight about how to create new connection classes.
View
51 lib/Predis/Client.php
@@ -32,7 +32,7 @@ class Client
private $options;
private $profile;
private $connection;
- private $connectionFactory;
+ private $connections;
/**
* Initializes a new client with optional connection parameters and client options.
@@ -43,15 +43,16 @@ class Client
public function __construct($parameters = null, $options = null)
{
$options = $this->filterOptions($options);
- $profile = $options->profile;
+ $profile = $options->profile;
if (isset($options->prefix)) {
$profile->setProcessor($options->prefix);
}
$this->options = $options;
$this->profile = $profile;
- $this->connectionFactory = $options->connections;
+ $this->connections = $options->connections;
+
$this->connection = $this->initializeConnection($parameters);
}
@@ -94,51 +95,15 @@ private function filterOptions($options)
*/
private function initializeConnection($parameters)
{
- if ($parameters === null) {
- return $this->createConnection(new ConnectionParameters());
- }
-
- if (is_array($parameters)) {
- if (isset($parameters[0])) {
- $cluster = $this->options->cluster;
- foreach ($parameters as $node) {
- $connection = $node instanceof IConnectionSingle ? $node : $this->createConnection($node);
- $cluster->add($connection);
- }
- return $cluster;
- }
- return $this->createConnection($parameters);
- }
-
if ($parameters instanceof IConnection) {
return $parameters;
}
- return $this->createConnection($parameters);
- }
-
- /**
- * Creates a new connection to a single server with the provided parameters.
- *
- * @param mixed $parameters Connection parameters.
- * @return IConnectionSingle
- */
- protected function createConnection($parameters)
- {
- $connection = $this->connectionFactory->create($parameters);
- $parameters = $connection->getParameters();
-
- if (isset($parameters->password)) {
- $command = $this->createCommand('auth', array($parameters->password));
- $connection->pushInitCommand($command);
- }
-
- if (isset($parameters->database)) {
- $command = $this->createCommand('select', array($parameters->database));
- $connection->pushInitCommand($command);
+ if (is_array($parameters) && isset($parameters[0])) {
+ return $this->connections->createCluster($this->options->cluster, $parameters, $this->profile);
}
- return $connection;
+ return $this->connections->create($parameters, $this->profile);
}
/**
@@ -168,7 +133,7 @@ public function getOptions()
*/
public function getConnectionFactory()
{
- return $this->connectionFactory;
+ return $this->connections;
}
/**
View
122 lib/Predis/ConnectionFactory.php
@@ -11,7 +11,10 @@
namespace Predis;
+use Predis\Profiles\IServerProfile;
use Predis\Network\IConnectionSingle;
+use Predis\Network\IConnectionCluster;
+use Predis\Profiles\ServerProfile;
/**
* Provides a default factory for Redis connections that maps URI schemes
@@ -22,22 +25,28 @@
*/
class ConnectionFactory implements IConnectionFactory
{
- private static $globalSchemes;
-
- private $instanceSchemes = array();
+ private $schemes;
/**
- * @param array $schemesMap Map of URI schemes to connection classes.
+ * Initializes a new instance of the default connection factory class used by Predis.
*/
- public function __construct(Array $schemesMap = null)
+ public function __construct()
{
- $this->instanceSchemes = self::ensureDefaultSchemes();
+ $this->schemes = $this->getDefaultSchemes();
+ }
- if (isset($schemesMap)) {
- foreach ($schemesMap as $scheme => $initializer) {
- $this->defineConnection($scheme, $initializer);
- }
- }
+ /**
+ * Returns a named array that maps URI schemes to connection classes.
+ *
+ * @return array Map of URI schemes and connection classes.
+ */
+ protected function getDefaultSchemes()
+ {
+ return array(
+ 'tcp' => 'Predis\Network\StreamConnection',
+ 'unix' => 'Predis\Network\StreamConnection',
+ 'http' => 'Predis\Network\WebdisConnection',
+ );
}
/**
@@ -46,81 +55,61 @@ public function __construct(Array $schemesMap = null)
* callable objects are used for lazy initialization of connection objects.
*
* @param mixed $initializer FQN of a connection class or a callable for lazy initialization.
+ * @return mixed
*/
- private static function checkConnectionInitializer($initializer)
+ protected function checkInitializer($initializer)
{
if (is_callable($initializer)) {
- return;
+ return $initializer;
}
$initializerReflection = new \ReflectionClass($initializer);
- if (!$initializerReflection->isSubclassOf('\Predis\Network\IConnectionSingle')) {
+ if (!$initializerReflection->isSubclassOf('Predis\Network\IConnectionSingle')) {
throw new \InvalidArgumentException(
'A connection initializer must be a valid connection class or a callable object'
);
}
- }
- /**
- * Ensures that the default global URI schemes map is initialized.
- *
- * @return array
- */
- private static function ensureDefaultSchemes()
- {
- if (!isset(self::$globalSchemes)) {
- self::$globalSchemes = array(
- 'tcp' => '\Predis\Network\StreamConnection',
- 'unix' => '\Predis\Network\StreamConnection',
- );
- }
-
- return self::$globalSchemes;
+ return $initializer;
}
/**
- * Defines a new URI scheme => connection class relation at class level.
- *
- * @param string $scheme URI scheme
- * @param mixed $connectionInitializer FQN of a connection class or a callable for lazy initialization.
+ * {@inheritdoc}
*/
- public static function define($scheme, $connectionInitializer)
+ public function define($scheme, $initializer)
{
- self::ensureDefaultSchemes();
- self::checkConnectionInitializer($connectionInitializer);
- self::$globalSchemes[$scheme] = $connectionInitializer;
+ $this->schemes[$scheme] = $this->checkInitializer($initializer);
}
/**
- * Defines a new URI scheme => connection class relation at instance level.
- *
- * @param string $scheme URI scheme
- * @param mixed $connectionInitializer FQN of a connection class or a callable for lazy initialization.
+ * {@inheritdoc}
*/
- public function defineConnection($scheme, $connectionInitializer)
+ public function undefine($scheme)
{
- self::checkConnectionInitializer($connectionInitializer);
- $this->instanceSchemes[$scheme] = $connectionInitializer;
+ unset($this->schemes[$scheme]);
}
/**
* {@inheritdoc}
*/
- public function create($parameters)
+ public function create($parameters, IServerProfile $profile = null)
{
if (!$parameters instanceof IConnectionParameters) {
- $parameters = new ConnectionParameters($parameters);
+ $parameters = new ConnectionParameters($parameters ?: array());
}
$scheme = $parameters->scheme;
- if (!isset($this->instanceSchemes[$scheme])) {
+ if (!isset($this->schemes[$scheme])) {
throw new \InvalidArgumentException("Unknown connection scheme: $scheme");
}
- $initializer = $this->instanceSchemes[$scheme];
+ $initializer = $this->schemes[$scheme];
if (!is_callable($initializer)) {
- return new $initializer($parameters);
+ $connection = new $initializer($parameters);
+ $this->prepareConnection($connection, $profile ?: ServerProfile::getDefault());
+
+ return $connection;
}
$connection = call_user_func($initializer, $parameters);
@@ -133,4 +122,37 @@ public function create($parameters)
return $connection;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createCluster(IConnectionCluster $cluster, $parameters, IServerProfile $profile = null)
+ {
+ foreach ($parameters as $node) {
+ $cluster->add($node instanceof IConnectionSingle ? $node : $this->create($node, $profile));
+ }
+
+ return $cluster;
+ }
+
+ /**
+ * Prepares a connection object after its initialization.
+ *
+ * @param IConnectionSingle $connection Instance of a connection object.
+ * @param IServerProfile $profile $connection Instance of a connection object.
+ */
+ protected function prepareConnection(IConnectionSingle $connection, IServerProfile $profile)
+ {
+ $parameters = $connection->getParameters();
+
+ if (isset($parameters->password)) {
+ $command = $profile->createCommand('auth', array($parameters->password));
+ $connection->pushInitCommand($command);
+ }
+
+ if (isset($parameters->database)) {
+ $command = $profile->createCommand('select', array($parameters->database));
+ $connection->pushInitCommand($command);
+ }
+ }
}
View
29 lib/Predis/IConnectionFactory.php
@@ -11,6 +11,9 @@
namespace Predis;
+use Predis\Profiles\IServerProfile;
+use Predis\Network\IConnectionCluster;
+
/**
* Interface that must be implemented by classes that provide their own mechanism
* to create and initialize new instances of Predis\Network\IConnectionSingle.
@@ -20,10 +23,34 @@
interface IConnectionFactory
{
/**
+ * Defines or overrides the connection class identified by a scheme prefix.
+ *
+ * @param string $scheme URI scheme identifying the connection class.
+ * @param mixed $initializer FQN of a connection class or a callable object for lazy initialization.
+ */
+ public function define($scheme, $initializer);
+
+ /**
+ * Undefines the connection identified by a scheme prefix.
+ *
+ * @param string $scheme Parameters for the connection.
+ */
+ public function undefine($scheme);
+
+ /**
* Creates a new connection object.
*
* @param mixed $parameters Parameters for the connection.
* @return Predis\Network\IConnectionSingle
*/
- public function create($parameters);
+ public function create($parameters, IServerProfile $profile = null);
+
+ /**
+ * Prepares a cluster of connection objects.
+ *
+ * @param IConnectionCluster Instance of a connection cluster class.
+ * @param array $parameters List of parameters for each connection object.
+ * @return Predis\Network\IConnectionCluster
+ */
+ public function createCluster(IConnectionCluster $cluster, $parameters, IServerProfile $profile = null);
}
View
6 lib/Predis/Options/ClientConnectionFactory.php
@@ -30,7 +30,11 @@ public function validate($value)
return $value;
}
if (is_array($value)) {
- return new ConnectionFactory($value);
+ $factory = $this->getDefault();
+ foreach ($value as $scheme => $initializer) {
+ $factory->define($scheme, $initializer);
+ }
+ return $factory;
}
}

0 comments on commit 728afe7

Please sign in to comment.
Something went wrong with that request. Please try again.