Commit Graph

252 Commits

Author SHA1 Message Date
Daniele Alessandri aa5c893d5a [phpdoc] Fix undefined namespaces. 2014-07-27 21:57:40 +02:00
Daniele Alessandri fff303a03b Comply with PSR-2 on intentional fall-through in non-empty case. 2014-07-27 21:57:40 +02:00
Daniele Alessandri 78ec22563a The \Iterator interface returns void for next(). 2014-07-27 21:57:40 +02:00
Daniele Alessandri 30254a2594 [phpdoc] Various phpdoc fixes. 2014-07-27 21:57:13 +02:00
Daniele Alessandri b230e243f5 Predis\PubSub\DispatcherLoop should take a PubSub consumer instance. 2014-07-27 16:53:46 +02:00
Daniele Alessandri 558e10963c Merge branch 'v1.0/refactor-cluster-internals' 2014-07-25 10:58:03 +02:00
Daniele Alessandri fdf5894022 Make connection factory mandatory for RedisCluster constructor. 2014-07-23 11:13:09 +02:00
Daniele Alessandri 6147f34478 [tests] Fix wrong test. 2014-07-23 11:06:35 +02:00
Daniele Alessandri 2ff8c37104 Redesign the whole internals for clustering.
This change actually had a positive impact on the design of the whole
internals for clustering which is now cleaner and easier to maintain.
It is still far from perfect, but we also have to keep performances in
consideration so we can say that we ended up with a good compromise.

Previously Predis assigned an hash to each command instance which was
computed from its key, now we changed approach and the library caches
the slot assigned to each command. This works for both our client-side
sharding cluster and the upcoming redis-cluster, but the former is the
one that needed most changes.

The PredisCluster aggregate connection now only takes an instance of
StrategyInterface, which in turn wraps the chosen distributor. After
all, in order to be able to calculate the assigned slot for a command
or key, the cluster strategy must have access to the distributor that
manages the distribution of the whole keyspace. Nothing really changes
in terms of configurability as it is still possible to decide which
distributor to use for client-side sharding, it is simply different:

  $distributor = new Predis\Cluster\Distribution\KetamaRing();
  $strategy = new Predis\Cluster\PredisStrategy($distributor);
  $cluster = new Predis\Connection\Aggregate\PredisCluster($strategy);

As for the RedisCluster aggregate connection, the only change is that
the mathematical operation of calculating the assigned slot from a key
has been completely moved inside the cluster strategy instance.

The strategy for redis-cluster does not use external distributors so
trying to StrategyInterface::getDistributor() will throw an exception.
This may change in future releases, but this is not a priority since
redis-cluster relies on a fixed, well-defined distribution mechanism.
2014-07-22 18:13:12 +02:00
Daniele Alessandri 346986099d Rename method "enableAutoSlotsMap()" to "useClusterSlots()". 2014-07-21 14:38:20 +02:00
Daniele Alessandri 4ab2bcea64 Fetch updated slots map from node indicated by -MOVED response.
This optimization makes it possible to fetch the slots map directly
from the server indicated by the -MOVED response eliminating the need
to use a random node in the pool, which in turn could require Predis
to open a new and useless connection.
2014-07-21 14:02:48 +02:00
Daniele Alessandri bd00b8cfe2 Fetch cluster slots from node upon first -MOVED response.
This is a more sane default as it allows users to indicate only a few
servers of the whole cluster composition, while it previously required
a more complex configuration of the client using client options.

This feature can be disabled using the "enableAutoSlotsMap()" method.
2014-07-21 14:02:43 +02:00
Daniele Alessandri a32eaf627b Remove useless method.
It is better to wrap explicitly a multibulk response iterator into a
multibulk tuple response iterator instead of hard-coding that into a
specialized method.
2014-07-21 11:18:25 +02:00
Daniele Alessandri e89f5cbc39 Add method to get connection factory from redis-cluster connection. 2014-07-21 11:11:52 +02:00
Daniele Alessandri 4188dc51bf Make it possible to specify a custom strategy for redis-cluster. 2014-07-21 10:56:32 +02:00
Daniele Alessandri eb8de52269 New command: COMMAND (Redis 3.0.0).
The command returns the response as is, but it would probably be not a
bad idea to parse it to restructure returned info using named arrays,
making it easier to access single commands and their info.

We will keep it as is for now, and investigate this change later.
2014-07-18 12:56:34 +02:00
Daniele Alessandri 202c558103 Run php-cs against source code. 2014-07-17 15:59:43 +02:00
Daniele Alessandri 89e662dc89 Use same strategy for both client-side sharding and redis-cluster.
This change is possible because, after a few changes in redis-cluster,
our default cluster strategy used for client side sharding and the one
used for redis-cluster turned out to be exactly the same, except for
the hashing function used to calculate distribution.

Actually some checks used to enforce correctness are redundant in the
context of redis-cluster (e.g. the one used to make sure that keys in
requests performing cross-keys operations will hash to the same slot,
which is performed by the server) so we could also add a more dumb and
permissive cluster strategy that relies on checks performed by Redis.

Differently to v0.8, the strategy for client-side sharding now uses
the same rules for extracting hash tags from keys especially when
empty tags are found in the string.
2014-07-17 12:48:46 +02:00
Daniele Alessandri 356f22a062 Implement PING in PUB/SUB loop abstraction for Redis 3.0.0. 2014-07-17 12:16:54 +02:00
Daniele Alessandri 88da187344 Add dedicated server profile for Redis 3.0. 2014-07-16 12:59:48 +02:00
Daniele Alessandri 2e0c55ac57 Remove support for Redis 1.2.
Actually we have just removed the server profile so nothing stops you
from reimplementing it, but Redis 2.0 has been released 4 years ago so
we are speaking of ancient releases that should probably not even be
used anymore.
2014-07-16 11:14:36 +02:00
Daniele Alessandri 9edc11dc8e Switch to CLUSTER SLOTS instead of CLUSTER NODES for redis-cluster.
CLUSTER SLOTS returns a structured response easier to handle compared
to the bulk response of CLUSTER NODES which must be parsed making the
whole thing more fragile.

CLUSTER SLOTS has been added in Redis 3.0.0b7.
2014-07-15 18:52:09 +02:00
Daniele Alessandri 959734cf8c Porperly handle -ERR instead of +QUEUED inside MULTI ... EXEC.
Error responses such as -OOM or -ERR on invalid arguments in commands
are returned immediatly instead of +QUEUED when using a transaction,
which is a condition that had not been tested enough. This condition
led to a bug in which Predis was not invalidating the transaction, so
when trying to create a new transaction Redis returned a "-ERR MULTI
calls can not be nested".

This commit fixes #187.
2014-07-14 16:28:29 +02:00
Ian Babrou 5b4a7970bb returning associative array from zrange command family 2014-07-14 13:16:26 +04:00
Daniele Alessandri a2265b12b3 Remove implementation of Predis\Command\RawCommand::__toString().
See #151 and message of commit 5c5dd40, forgot to apply the same
change to the Predis\Command\RawCommand class.
2014-06-12 11:57:54 +02:00
Daniele Alessandri e575c32cb4 Rename RedisCluster::askClusterNodes() to askSlotsMap().
This is more consistent with the actual purpose of this method and
more in-line with a possible future change in the underlying command
used to retrieve the slots map if redis-cluster will implement the
CLUSTER SLOTS command.
2014-06-10 10:36:17 +02:00
Daniele Alessandri 42f237e306 [tests] Use annotations to specify expected Redis server version.
This change targets only method annotations and aims to make the body
of tests more readable using the @requiresRedisVersion annotation.

Tests using this annotation requires to be assigned the "connected"
group of tests because they create a connection to the Redis instance
specified in phpunit.xml to fetch its the version.

This is a quick example of how this annotation can be used:

    /**
     * @group connected
     * @requiresRedisVersion >= 2.8.9
     */
    public function testExecutedOnlyWithMatchingRedisVersion()
    {
    }

Future improvements (currently not needed) include:

  * Same annotation working on a class-level (but still applied only
    to test methods with an explicitly assigned @group connected).

  * Ability to specify a version range.

Meh

Meh
2014-06-09 17:31:18 +02:00
Daniele Alessandri 940326e5bd New command: ZREMRANGEBYLEX (Redis 2.8.9). 2014-06-09 15:35:28 +02:00
Daniele Alessandri ea32f74512 New command: ZRANGEBYLEX (Redis 2.8.9). 2014-06-09 15:26:17 +02:00
Daniele Alessandri 8dbac3dd73 New command: ZLEXCOUNT (Redis 2.8.9). 2014-06-09 15:17:36 +02:00
Daniele Alessandri 5a474c5a32 Rename alias used in Predis\Client for Predis\Transaction\MultiExec. 2014-06-03 18:56:48 +02:00
Daniele Alessandri 0148743a76 Fix parsing of the output of CLUSTER NODES to fetch slots map.
There was an error in presence of slaves in the cluster configuration,
see #165 for reference.
2014-06-03 16:24:27 +02:00
Daniele Alessandri 1fd113c570 Rename ComposableProtocolProcessor to CompositeProtocolProcessor. 2014-06-03 15:45:40 +02:00
Daniele Alessandri abd284c972 Complete reorganization of the Predis\Connection namespace.
* Renamed SingleConnectionInterface to NodeConnectionInterface since
  this name is better and makes even more sense in the context of
  cluster and replication scenarios.

* Moved specialized aggregate connections (the ones implementing both
  predis and redis cluster and master/slave replication) in a newly
  created Predis\Connection\Aggregate sub-namespace.

* Removed the "Connection" part from names of aggregate connection
  interfaces in the Predis\Connection\Aggregate sub-namespace.

* Changed "Composable" to "Composite" in the name of interfaces and
  classes that can use pluggable protocol processors.
2014-06-03 15:19:32 +02:00
Daniele Alessandri 87417f4d7e Skip integration tests for HyperLogLog commands on Redis < 2.8.9.
Caught this by running the test suite on TravisCI which still runs an
older version of Redis 2.8. We should find a more decent way to handle
differences in profiles when commands get added between patch releases
of Redis, our custom skip method will do for now.
2014-05-30 12:19:05 +02:00
Daniele Alessandri 2aa0b071fc New commands: PFADD, PFCOUNT, PFMERGE (Redis 2.8.9).
Many thanks to @rubensayshi for his initial commits on this in #163,
but I had to start from scratch for the master branch first.
2014-05-30 11:32:39 +02:00
Alexey Kupershtokh f784dfad84 Enable INCRBYFLOAT in cluster mode 2014-05-28 13:00:24 +02:00
Daniele Alessandri 5c5dd40527 Remove implementation of Predis\Command\Command::__toString().
Issue #151 pointed to a flaw in how command instances were converted
to strings: we were simply truncating their arguments when exceeding
a certain size as this was mostly intended for logging or debugging,
but this approach breaks strings containing multibyte characters so
we decided to drop this feature altogether for the sake of simplicity.

It is still possible to replicate the same (and eventually improved)
behavior externally by fetching ID and arguments of a command out of
a command instance using the public methods made available by the
Predis\Command\CommandInterface.
2014-03-25 15:32:20 +01:00
Daniele Alessandri e23fd9bea8 Use redis-cluster rules for empty key tags for client-side sharding.
This commit represents a breaking change when the first occurrence of
"{}" is found in a key because it will produce a different hash than
previous versions of Predis, thus leading to a different partitioning.

If you really need to stick with the old behavior, you can subclass
Predis\Cluster\PredisStrategy and override extractKeyTag() using the
old implementation of this method and pass the strategy instance when
initializing the cluster connection via client options.
2014-02-11 19:06:47 +01:00
Daniele Alessandri 8fbe658ca8 Fix implementation for hash tags extraction from keys.
We now fully comply with the specifications defined by Redis.
2014-02-11 19:06:44 +01:00
Daniele Alessandri 26289f47ec Add support for key hash tags in redis-cluster (Redis 3.0.0b1).
Multi-keys operations are not allowed even when keys generate the same
hash but this will probably be supported in later betas of Redis which
means we will basically end up reusing the whole strategy used for
client-side sharding.

Ported from the v0.8 branch.
2014-02-11 15:44:37 +01:00
Daniele Alessandri ae61a0fd2b [tests] Use Predis\Autoload from include_path when not in repository.
This is useful only for running the test suite after installing the
PEAR package, see #126 for reference.
2014-01-08 17:34:41 +01:00
Daniele Alessandri bf32f4b87c [tests] Remove unused "use" directives. 2013-12-22 16:19:04 +01:00
Daniele Alessandri 46671b9095 Run php-cs against test suite.
[ci skip]
2013-12-22 16:18:59 +01:00
Daniele Alessandri cfa456fdd1 [tests] Fix a couple of innocuous glitches. 2013-12-22 15:00:51 +01:00
Daniele Alessandri 6a577a0eb5 Apply more phpdoc fixes. 2013-12-22 15:00:51 +01:00
Daniele Alessandri 8357af177e [test] Fix wrong variable. 2013-12-22 15:00:50 +01:00
Daniele Alessandri 7ebb8a8b42 [tests] Fix a couple of glitches in our base PHPUnit classes. 2013-12-22 15:00:50 +01:00
Daniele Alessandri 728d9dceb5 [tests] No need to reassign $exception. 2013-12-22 15:00:41 +01:00
Daniele Alessandri 3befbb3ac2 Make Pipeline::executeCommand() return $this for fluent interface. 2013-12-22 13:40:36 +01:00