From 2ba15eb555b5cda349b0211b11bb70883f27af25 Mon Sep 17 00:00:00 2001 From: Chris Boulton Date: Sat, 12 Jan 2013 23:37:38 +1100 Subject: [PATCH] replace Redisent with Credis (also adds native phpredis support) --- CHANGELOG.md | 8 + composer.json | 9 +- composer.lock | 399 ++----------------------------- lib/Redisent/LICENSE | 22 -- lib/Redisent/README.markdown | 67 ------ lib/Redisent/Redisent.php | 165 ------------- lib/Redisent/RedisentCluster.php | 138 ----------- lib/Resque.php | 16 +- lib/Resque/Redis.php | 57 +++-- lib/Resque/RedisCluster.php | 117 --------- test/Resque/Tests/TestCase.php | 2 +- 11 files changed, 81 insertions(+), 919 deletions(-) delete mode 100644 lib/Redisent/LICENSE delete mode 100644 lib/Redisent/README.markdown delete mode 100644 lib/Redisent/Redisent.php delete mode 100644 lib/Redisent/RedisentCluster.php delete mode 100644 lib/Resque/RedisCluster.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e27544..f6f1196 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ **Note:** This release introduces backwards incompatible changes with all previous versions of php-resque. Please see below for details. +### Redisent (Redis Library) Replaced with Credis + +Redisent has always been the Redis backend for php-resque because of its lightweight nature. Unfortunately, Redisent is largely unmaintained. + +[Credis](http://example.com/) is a fork of Redisent, which among other improvements will automatically use the [phpredis](https://github.com/nicolasff/phpredis) native PHP extension if it is available. (you want this for speed, trust me) + +php-resque now utilizes Credis for all Redis based operations. Credis automatically required and installed as a Composer dependency. + ### Composer Support Composer support has been improved and is now the recommended method for including php-resque in your project. Details on Composer support can be found in the Getting Started section of the readme. diff --git a/composer.json b/composer.json index a3880ae..9b67eae 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,15 @@ "email": "chris@bigcommerce.com" } ], + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/chrisboulton/credis" + } + ], "require": { - "php": ">=5.3.0" + "php": ">=5.3.0", + "colinmollenhour/credis": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.*" diff --git a/composer.lock b/composer.lock index 91301f7..472226f 100644 --- a/composer.lock +++ b/composer.lock @@ -1,408 +1,53 @@ { - "hash": "b05c2c31be6cac834e33b1a7fe61d063", + "hash": "af626b3a277bd0ab503c2c107327a88e", "packages": [ - - ], - "packages-dev": [ { - "name": "phpunit/php-code-coverage", - "version": "1.2.7", + "name": "colinmollenhour/credis", + "version": "dev-master", "source": { "type": "git", - "url": "git://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1.2.7" + "url": "https://github.com/chrisboulton/credis", + "reference": "62c73dd16e08069e3fd8f224cb4a5ddd73db8095" }, "dist": { "type": "zip", - "url": "https://github.com/sebastianbergmann/php-code-coverage/archive/1.2.7.zip", - "reference": "1.2.7", + "url": "https://api.github.com/repos/chrisboulton/credis/zipball/62c73dd16e08069e3fd8f224cb4a5ddd73db8095", + "reference": "62c73dd16e08069e3fd8f224cb4a5ddd73db8095", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-token-stream": ">=1.1.3@stable", - "phpunit/php-text-template": ">=1.1.1@stable" + "php": ">=5.3.0" }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" - }, - "time": "2012-12-02 14:54:55", + "time": "2013-01-12 10:15:31", "type": "library", "autoload": { "classmap": [ - "PHP/" + "Client.php", + "Cluster.php" ] }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "testing", - "coverage", - "xunit" - ] - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.3", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "1.3.3" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", - "reference": "1.3.3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2012-10-11 04:44:38", - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "filesystem", - "iterator" - ] - }, - { - "name": "phpunit/php-text-template", - "version": "1.1.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-text-template.git", - "reference": "1.1.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", - "reference": "1.1.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2012-10-31 11:15:28", - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ] - }, - { - "name": "phpunit/php-timer", - "version": "1.0.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-timer.git", - "reference": "1.0.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", - "reference": "1.0.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2012-10-11 04:45:58", - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "timer" - ] - }, - { - "name": "phpunit/php-token-stream", - "version": "1.1.5", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1.1.5" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", - "reference": "1.1.5", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "time": "2012-10-11 04:47:14", - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "tokenizer" - ] - }, - { - "name": "phpunit/phpunit", - "version": "3.7.12", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.12" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/phpunit/archive/3.7.12.zip", - "reference": "3.7.12", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.1", - "phpunit/php-text-template": ">=1.1.1", - "phpunit/php-code-coverage": ">=1.2.1", - "phpunit/php-timer": ">=1.0.2", - "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", - "symfony/yaml": ">=2.1.0,<2.2.0", - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*" - }, - "suggest": { - "phpunit/php-invoker": ">=1.1.0", - "ext-json": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*" - }, - "time": "2013-01-09 22:41:02", - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "testing", - "phpunit", - "xunit" - ] - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.2", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "1.2.2" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.2.zip", - "reference": "1.2.2", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "time": "2012-11-05 10:39:13", - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ] - }, - { - "name": "symfony/yaml", - "version": "v2.1.6", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml", - "reference": "v2.1.6" - }, - "dist": { - "type": "zip", - "url": "https://github.com/symfony/Yaml/archive/v2.1.6.zip", - "reference": "v2.1.6", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2012-12-06 10:00:55", - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml": "" - } - }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" } ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com" + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "support": { + "source": "https://github.com/chrisboulton/credis/tree/master" + } } ], + "packages-dev": null, "aliases": [ ], "minimum-stability": "stable", - "stability-flags": [ - - ] + "stability-flags": { + "colinmollenhour/credis": 20 + } } diff --git a/lib/Redisent/LICENSE b/lib/Redisent/LICENSE deleted file mode 100644 index 385910f..0000000 --- a/lib/Redisent/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009 Justin Poliey - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/Redisent/README.markdown b/lib/Redisent/README.markdown deleted file mode 100644 index 3edb843..0000000 --- a/lib/Redisent/README.markdown +++ /dev/null @@ -1,67 +0,0 @@ -# Redisent - -Redisent is a simple, no-nonsense interface to the [Redis](http://code.google.com/p/redis/) key-value store for modest developers. -Due to the way it is implemented, it is flexible and tolerant of changes to the Redis protocol. - -## Getting to work - -If you're at all familiar with the Redis protocol and PHP objects, you've already mastered Redisent. -All Redisent does is map the Redis protocol to a PHP object, abstract away the nitty-gritty, and make the return values PHP compatible. - - require 'redisent.php'; - $redis = new Redisent('localhost'); - $redis->set('awesome', 'absolutely'); - echo sprintf('Is Redisent awesome? %s.\n', $redis->get('awesome')); - -You use the exact same command names, and the exact same argument order. **How wonderful.** How about a more complex example? - - require 'redisent.php'; - $redis = new Redisent('localhost'); - $redis->rpush('particles', 'proton'); - $redis->rpush('particles', 'electron'); - $redis->rpush('particles', 'neutron'); - $particles = $redis->lrange('particles', 0, -1); - $particle_count = $redis->llen('particles'); - echo "

The {$particle_count} particles that make up atoms are:

"; - echo ""; - -Be aware that Redis error responses will be wrapped in a RedisException class and thrown, so do be sure to use proper coding techniques. - -## Clustering your servers - -Redisent also includes a way for developers to fully utilize the scalability of Redis with multiple servers and [consistent hashing](http://en.wikipedia.org/wiki/Consistent_hashing). -Using the RedisentCluster class, you can use Redisent the same way, except that keys will be hashed across multiple servers. -Here is how to set up a cluster: - - include 'redisent_cluster.php'; - - $cluster = new RedisentCluster(array( - array('host' => '127.0.0.1', 'port' => 6379), - array('host' => '127.0.0.1', 'port' => 6380) - )); - -You can then use Redisent the way you normally would, i.e., `$cluster->set('key', 'value')` or `$cluster->lrange('particles', 0, -1)`. -But what about when you need to use commands that are server specific and do not operate on keys? You can use routing, with the `RedisentCluster::to` method. -To use routing, you need to assign a server an alias in the constructor of the Redis cluster. Aliases are not required on all servers, just the ones you want to be able to access directly. - - include 'redisent_cluster.php'; - - $cluster = new RedisentCluster(array( - 'alpha' => array('host' => '127.0.0.1', 'port' => 6379), - array('host' => '127.0.0.1', 'port' => 6380) - )); - -Now there is an alias of the server running on 127.0.0.1:6379 called **alpha**, and can be interacted with like this: - - // get server info - $cluster->to('alpha')->info(); - -Now you have complete programatic control over your Redis servers. - -## About - -© 2009 [Justin Poliey](http://justinpoliey.com) \ No newline at end of file diff --git a/lib/Redisent/Redisent.php b/lib/Redisent/Redisent.php deleted file mode 100644 index 92ccd02..0000000 --- a/lib/Redisent/Redisent.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @copyright 2009 Justin Poliey - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - * @package Redisent - */ - -define('CRLF', sprintf('%s%s', chr(13), chr(10))); - -/** - * Wraps native Redis errors in friendlier PHP exceptions - * Only declared if class doesn't already exist to ensure compatibility with php-redis - */ -if (! class_exists('RedisException', false)) { - class RedisException extends Exception { - } -} - -/** - * Redisent, a Redis interface for the modest among us - */ -class Redisent { - - /** - * Socket connection to the Redis server - * @var resource - * @access private - */ - private $__sock; - - /** - * Host of the Redis server - * @var string - * @access public - */ - public $host; - - /** - * Port on which the Redis server is running - * @var integer - * @access public - */ - public $port; - - /** - * Number of times to attempt a reconnect - * - * @var int - */ - public $max_reconnects = 3; - - /** - * Creates a Redisent connection to the Redis server on host {@link $host} and port {@link $port}. - * @param string $host The hostname of the Redis server - * @param integer $port The port number of the Redis server - */ - function __construct($host, $port = 6379) { - $this->host = $host; - $this->port = $port; - $this->establishConnection(); - } - - function establishConnection() { - $this->__sock = fsockopen($this->host, $this->port, $errno, $errstr); - if (!$this->__sock) { - throw new Exception("{$errno} - {$errstr}"); - } - } - - function __destruct() { - fclose($this->__sock); - } - - function __call($name, $args) { - - /* Build the Redis unified protocol command */ - array_unshift($args, strtoupper($name)); - $command = sprintf('*%d%s%s%s', count($args), CRLF, implode(array_map(array($this, 'formatArgument'), $args), CRLF), CRLF); - - /* Open a Redis connection and execute the command */ - $reconnects = 0; - for ($written = 0; $written < strlen($command); $written += $fwrite) { - $fwrite = @fwrite($this->__sock, substr($command, $written)); - if ($fwrite === FALSE || $fwrite === 0) { - if ($reconnects >= (int)$this->max_reconnects) { - throw new Exception('Failed to write entire command to stream'); - }else{ - fclose($this->__sock); - sleep(1); - $this->establishConnection(); - $reconnects++; - } - } - } - - /* Parse the response based on the reply identifier */ - $reply = trim(fgets($this->__sock, 512)); - switch (substr($reply, 0, 1)) { - /* Error reply */ - case '-': - throw new RedisException(substr(trim($reply), 4)); - break; - /* Inline reply */ - case '+': - $response = substr(trim($reply), 1); - break; - /* Bulk reply */ - case '$': - $response = null; - if ($reply == '$-1') { - break; - } - $read = 0; - $size = substr($reply, 1); - do { - $block_size = ($size - $read) > 1024 ? 1024 : ($size - $read); - $response .= fread($this->__sock, $block_size); - $read += $block_size; - } while ($read < $size); - fread($this->__sock, 2); /* discard crlf */ - break; - /* Multi-bulk reply */ - case '*': - $count = substr($reply, 1); - if ($count == '-1') { - return null; - } - $response = array(); - for ($i = 0; $i < $count; $i++) { - $bulk_head = trim(fgets($this->__sock, 512)); - $size = substr($bulk_head, 1); - if ($size == '-1') { - $response[] = null; - } - else { - $read = 0; - $block = ""; - do { - $block_size = ($size - $read) > 1024 ? 1024 : ($size - $read); - $block .= fread($this->__sock, $block_size); - $read += $block_size; - } while ($read < $size); - fread($this->__sock, 2); /* discard crlf */ - $response[] = $block; - } - } - break; - /* Integer reply */ - case ':': - $response = intval(substr(trim($reply), 1)); - break; - default: - throw new RedisException("invalid server response: {$reply}"); - break; - } - /* Party on */ - return $response; - } - - private function formatArgument($arg) { - return sprintf('$%d%s%s', strlen($arg), CRLF, $arg); - } -} \ No newline at end of file diff --git a/lib/Redisent/RedisentCluster.php b/lib/Redisent/RedisentCluster.php deleted file mode 100644 index 215726e..0000000 --- a/lib/Redisent/RedisentCluster.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright 2009 Justin Poliey - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - * @package Redisent - */ - -require_once __DIR__ . '/Redisent.php'; - -/** - * A generalized Redisent interface for a cluster of Redis servers - */ -class RedisentCluster { - - /** - * Collection of Redisent objects attached to Redis servers - * @var array - * @access private - */ - private $redisents; - - /** - * Aliases of Redisent objects attached to Redis servers, used to route commands to specific servers - * @see RedisentCluster::to - * @var array - * @access private - */ - private $aliases; - - /** - * Hash ring of Redis server nodes - * @var array - * @access private - */ - private $ring; - - /** - * Individual nodes of pointers to Redis servers on the hash ring - * @var array - * @access private - */ - private $nodes; - - /** - * Number of replicas of each node to make around the hash ring - * @var integer - * @access private - */ - private $replicas = 128; - - /** - * The commands that are not subject to hashing - * @var array - * @access private - */ - private $dont_hash = array( - 'RANDOMKEY', 'DBSIZE', - 'SELECT', 'MOVE', 'FLUSHDB', 'FLUSHALL', - 'SAVE', 'BGSAVE', 'LASTSAVE', 'SHUTDOWN', - 'INFO', 'MONITOR', 'SLAVEOF' - ); - - /** - * Creates a Redisent interface to a cluster of Redis servers - * @param array $servers The Redis servers in the cluster. Each server should be in the format array('host' => hostname, 'port' => port) - */ - function __construct($servers) { - $this->ring = array(); - $this->aliases = array(); - foreach ($servers as $alias => $server) { - $this->redisents[] = new Redisent($server['host'], $server['port']); - if (is_string($alias)) { - $this->aliases[$alias] = $this->redisents[count($this->redisents)-1]; - } - for ($replica = 1; $replica <= $this->replicas; $replica++) { - $this->ring[crc32($server['host'].':'.$server['port'].'-'.$replica)] = $this->redisents[count($this->redisents)-1]; - } - } - ksort($this->ring, SORT_NUMERIC); - $this->nodes = array_keys($this->ring); - } - - /** - * Routes a command to a specific Redis server aliased by {$alias}. - * @param string $alias The alias of the Redis server - * @return Redisent The Redisent object attached to the Redis server - */ - function to($alias) { - if (isset($this->aliases[$alias])) { - return $this->aliases[$alias]; - } - else { - throw new Exception("That Redisent alias does not exist"); - } - } - - /* Execute a Redis command on the cluster */ - function __call($name, $args) { - - /* Pick a server node to send the command to */ - $name = strtoupper($name); - if (!in_array($name, $this->dont_hash)) { - $node = $this->nextNode(crc32($args[0])); - $redisent = $this->ring[$node]; - } - else { - $redisent = $this->redisents[0]; - } - - /* Execute the command on the server */ - return call_user_func_array(array($redisent, $name), $args); - } - - /** - * Routes to the proper server node - * @param integer $needle The hash value of the Redis command - * @return Redisent The Redisent object associated with the hash - */ - private function nextNode($needle) { - $haystack = $this->nodes; - while (count($haystack) > 2) { - $try = floor(count($haystack) / 2); - if ($haystack[$try] == $needle) { - return $needle; - } - if ($needle < $haystack[$try]) { - $haystack = array_slice($haystack, 0, $try + 1); - } - if ($needle > $haystack[$try]) { - $haystack = array_slice($haystack, $try + 1); - } - } - return $haystack[count($haystack)-1]; - } - -} \ No newline at end of file diff --git a/lib/Resque.php b/lib/Resque.php index c3254a3..88cec4c 100644 --- a/lib/Resque.php +++ b/lib/Resque.php @@ -71,21 +71,7 @@ class Resque $server = 'localhost:6379'; } - if(is_array($server)) { - self::$redis = new Resque_RedisCluster($server); - } - else { - if (strpos($server, 'unix:') === false) { - list($host, $port) = explode(':', $server); - } - else { - $host = $server; - $port = null; - } - self::$redis = new Resque_Redis($host, $port); - } - - self::$redis->select(self::$redisDatabase); + self::$redis = new Resque_Redis($server, self::$redisDatabase); return self::$redis; } diff --git a/lib/Resque/Redis.php b/lib/Resque/Redis.php index 1cff624..f6f6dc6 100644 --- a/lib/Resque/Redis.php +++ b/lib/Resque/Redis.php @@ -1,25 +1,22 @@ * @license http://www.opensource.org/licenses/mit-license.php */ -class Resque_Redis extends Redisent +class Resque_Redis { /** * Redis namespace * @var string */ private static $defaultNamespace = 'resque:'; + + private $server; + private $database; + /** * @var array List of all commands in Redis that supply a key as their * first argument. Used to prefix keys with the Resque namespace. @@ -81,7 +78,7 @@ class Resque_Redis extends Redisent // msetnx // mset // renamenx - + /** * Set Redis namespace (prefix) default: resque * @param string $namespace @@ -93,7 +90,36 @@ class Resque_Redis extends Redisent } self::$defaultNamespace = $namespace; } - + + public function __construct($server, $database = null) + { + $this->server = $server; + $this->database = $database; + + if (is_array($this->server)) { + $this->driver = new Credis_Cluster($server); + } + else { + $port = null; + $host = $server; + + // If not a UNIX socket path or tcp:// formatted connections string + // assume host:port combination. + if (strpos($server, '/') === false) { + $parts = explode(':', $server); + if (isset($parts[1])) { + $port = $parts[1]; + } + $host = $parts[0]; + } + $this->driver = new Credis_Client($host, $port); + } + + if ($this->database !== null) { + $this->driver->select($database); + } + } + /** * Magic method to handle all function requests and prefix key based * operations with the {self::$defaultNamespace} key prefix. @@ -103,14 +129,13 @@ class Resque_Redis extends Redisent * @return mixed Return value from Resident::call() based on the command. */ public function __call($name, $args) { - $args = func_get_args(); if(in_array($name, $this->keyCommands)) { - $args[1][0] = self::$defaultNamespace . $args[1][0]; + $args[0] = self::$defaultNamespace . $args[0]; } try { - return parent::__call($name, $args[1]); + return $this->driver->__call($name, $args); } - catch(RedisException $e) { + catch(CredisException $e) { return false; } } @@ -130,4 +155,4 @@ class Resque_Redis extends Redisent return $string; } } -?> +?> \ No newline at end of file diff --git a/lib/Resque/RedisCluster.php b/lib/Resque/RedisCluster.php deleted file mode 100644 index 21caeb7..0000000 --- a/lib/Resque/RedisCluster.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.php - */ -class Resque_RedisCluster extends RedisentCluster -{ - /** - * Redis namespace - * @var string - */ - private static $defaultNamespace = 'resque:'; - /** - * @var array List of all commands in Redis that supply a key as their - * first argument. Used to prefix keys with the Resque namespace. - */ - private $keyCommands = array( - 'exists', - 'del', - 'type', - 'keys', - 'expire', - 'ttl', - 'move', - 'set', - 'get', - 'getset', - 'setnx', - 'incr', - 'incrby', - 'decrby', - 'decrby', - 'rpush', - 'lpush', - 'llen', - 'lrange', - 'ltrim', - 'lindex', - 'lset', - 'lrem', - 'lpop', - 'rpop', - 'sadd', - 'srem', - 'spop', - 'scard', - 'sismember', - 'smembers', - 'srandmember', - 'zadd', - 'zrem', - 'zrange', - 'zrevrange', - 'zrangebyscore', - 'zcard', - 'zscore', - 'zremrangebyscore', - 'sort' - ); - // sinterstore - // sunion - // sunionstore - // sdiff - // sdiffstore - // sinter - // smove - // rename - // rpoplpush - // mget - // msetnx - // mset - // renamenx - - /** - * Set Redis namespace (prefix) default: resque - * @param string $namespace - */ - public static function prefix($namespace) - { - if (strpos($namespace, ':') === false) { - $namespace .= ':'; - } - self::$defaultNamespace = $namespace; - } - - /** - * Magic method to handle all function requests and prefix key based - * operations with the '{self::$defaultNamespace}' key prefix. - * - * @param string $name The name of the method called. - * @param array $args Array of supplied arguments to the method. - * @return mixed Return value from Resident::call() based on the command. - */ - public function __call($name, $args) { - $args = func_get_args(); - if(in_array($name, $this->keyCommands)) { - $args[1][0] = self::$defaultNamespace . $args[1][0]; - } - try { - return parent::__call($name, $args[1]); - } - catch(RedisException $e) { - return false; - } - } -} -?> diff --git a/test/Resque/Tests/TestCase.php b/test/Resque/Tests/TestCase.php index 6c052d3..4ed65de 100644 --- a/test/Resque/Tests/TestCase.php +++ b/test/Resque/Tests/TestCase.php @@ -15,7 +15,7 @@ class Resque_Tests_TestCase extends PHPUnit_Framework_TestCase { $config = file_get_contents(REDIS_CONF); preg_match('#^\s*port\s+([0-9]+)#m', $config, $matches); - $this->redis = new Redisent('localhost', $matches[1]); + $this->redis = new Credis_Client('localhost', $matches[1]); // Flush redis $this->redis->flushAll();