mirror of
https://github.com/predis/predis.git
synced 2026-09-02 13:49:32 +00:00
Redesign how Predis\ConnectionFactory works and make more sense out of it.
This commit is contained in:
+3
-1
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
+8
-43
@@ -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 @@ class Client
|
||||
*/
|
||||
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 (is_array($parameters) && isset($parameters[0])) {
|
||||
return $this->connections->createCluster($this->options->cluster, $parameters, $this->profile);
|
||||
}
|
||||
|
||||
if (isset($parameters->database)) {
|
||||
$command = $this->createCommand('select', array($parameters->database));
|
||||
$connection->pushInitCommand($command);
|
||||
}
|
||||
|
||||
return $connection;
|
||||
return $this->connections->create($parameters, $this->profile);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +133,7 @@ class Client
|
||||
*/
|
||||
public function getConnectionFactory()
|
||||
{
|
||||
return $this->connectionFactory;
|
||||
return $this->connections;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 @@ use Predis\Network\IConnectionSingle;
|
||||
*/
|
||||
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 @@ class ConnectionFactory implements IConnectionFactory
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static function define($scheme, $connectionInitializer)
|
||||
{
|
||||
self::ensureDefaultSchemes();
|
||||
self::checkConnectionInitializer($connectionInitializer);
|
||||
self::$globalSchemes[$scheme] = $connectionInitializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function defineConnection($scheme, $connectionInitializer)
|
||||
{
|
||||
self::checkConnectionInitializer($connectionInitializer);
|
||||
$this->instanceSchemes[$scheme] = $connectionInitializer;
|
||||
return $initializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function create($parameters)
|
||||
public function define($scheme, $initializer)
|
||||
{
|
||||
$this->schemes[$scheme] = $this->checkInitializer($initializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function undefine($scheme)
|
||||
{
|
||||
unset($this->schemes[$scheme]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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 @@ class ConnectionFactory implements IConnectionFactory
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -19,11 +22,35 @@ namespace Predis;
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ class ClientConnectionFactory extends Option
|
||||
return $value;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
return new ConnectionFactory($value);
|
||||
$factory = $this->getDefault();
|
||||
foreach ($value as $scheme => $initializer) {
|
||||
$factory->define($scheme, $initializer);
|
||||
}
|
||||
return $factory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user