Commit Graph

93 Commits

Author SHA1 Message Date
Daniele Alessandri 8dd9893a2f Run php-cs-fixer with new configuration. 2015-07-24 23:17:02 +02:00
Daniele Alessandri dbfc1a74ba More random fixes after inspection. 2014-07-27 23:06:17 +02:00
Daniele Alessandri f372029cfc Fix code smells. 2014-07-27 20:13:24 +02:00
Daniele Alessandri b230e243f5 Predis\PubSub\DispatcherLoop should take a PubSub consumer instance. 2014-07-27 16:53:46 +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 202c558103 Run php-cs against source code. 2014-07-17 15:59:43 +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 d1ec791ae9 Rename examples and update some comments.
[ci skip]
2013-12-21 10:50:08 +01:00
Daniele Alessandri cbf015164c Rename Predis\Client::raw() to Predis\Client::executeRaw().
This is more consistent with Predis\Client::executeRaw() and its more
explicit since simply "raw" as a method name was a bit too vague even
despite being nicely short.
2013-12-14 20:37:28 +01:00
Daniele Alessandri 8744285cb3 Ignoring the plural form of "reply" for renames is dumb...
[ci skip]
2013-12-10 18:08:14 +01:00
Daniele Alessandri 427309db69 Apply code styling fixes.
There is actually no need for such indentations.
2013-12-07 15:41:45 +01:00
Daniele Alessandri 373d30b070 Use Predis\Response\Status to identify all kinds of status responses.
Status response objects are needed mostly to make it possible from the
client perspective to differentiate a status response with the payload
"OK" from a normale bulk reply containing "OK".

The biggest change is for commands returning +OK responses: these were
previously translated to TRUE (bool value), but they are now returned
as instances of Predis\Response\Status. Just to illustrate an example
of the possibilities with this change we will use SET since it is the
most widely used command returning +OK:

  $response = $client->set('foo', 'bar');

  echo $response;         // 'OK'
  $response == 'OK';      // TRUE
  isset($response->ok);   // TRUE
  $response == true;      // TRUE
  $response === true;     // FALSE
  $response instanceof Predis\Response\ObjectInterface;     // TRUE
  $response instanceof Predis\Response\Status;              // TRUE

For those checking responses returned by commands such as SET or PONG,
the breaking change basically lies in the usage of strict comparison:
doing $response === true will now evaluate to FALSE instead of TRUE.

By default Predis caches common status responses such as OK or QUEUED
to lower the memory usage when using pipelines or transactions.
2013-12-07 15:15:23 +01:00
Daniele Alessandri ac8d0c1f42 Fix example.
[ci skip]
2013-12-02 16:12:43 +01:00
Daniele Alessandri 4bf0ee4c6a Rename ConnectionInterface::writeCommand() to writeRequest().
This name is more consistent with its counterpart, readResponse().
2013-12-02 11:08:14 +01:00
Daniele Alessandri a00ffbf53f Rework examples for plain Redis commands. 2013-12-01 13:42:10 +01:00
Daniele Alessandri 3c77d3b0c1 Update examples. 2013-12-01 11:28:56 +01:00
Daniele Alessandri 09895f27bf Rename command class for scripting to Predis\Command\ScriptCommand.
We also changed our wording to indentify this kind of abstraction so
instead of using "scripted commands" (kind of broken English) we now
use "scriptable commands".
2013-11-30 12:43:21 +01:00
Daniele Alessandri 2a5483df90 Reorganize the Predis\Profile namespace.
The profile factory code has been extrapolated into a the new class
Predis\Profile\Factory (final and with only static methods).
2013-11-22 12:01:29 +01:00
Daniele Alessandri 8068c87e47 Rewrite a good chunk of the classes in the Predis\Pipeline namespace.
First of all we completely removed the concept of pipeline executors.
Now pipelines can be easily customized by extending our default class
Predis\Pipeline\Pipeline.

Tests coverage for the Predis\Pipeline namespace is decent but can be
definitely improved while test cases can be beautified.
2013-11-16 21:23:49 +01:00
Daniele Alessandri e6f1788e27 Rename interfaces and classes in the Predis\Cluster namespace.
A few methods were renamed accordingly for consistency
2013-11-16 16:21:27 +01:00
Daniele Alessandri 9d2cb975eb Rename classes in Predis\Monitor namespace. 2013-11-16 15:42:56 +01:00
Daniele Alessandri c3a58dffdf Rename classes in the Predis\PubSub namespace. 2013-11-16 15:27:58 +01:00
Daniele Alessandri 7d60e995f8 Rename session handler class. 2013-11-16 15:03:05 +01:00
Daniele Alessandri bab0cd999c Rename Predis\Client::multiExec() to Predis\Client::transaction().
Method was deprecated since Predis v0.8.5.
2013-11-09 19:56:01 +01:00
Daniele Alessandri fb2d8a37c1 Drop support for streamable multibulk responses.
Supporting this feature has been problematic and leaded to some ugly
code to make abstractions such as pipelines and transactions aware of
these kind of response objects. Furthermore, it was not possible to
add them to all the connection classes due to implementation limits.

For such reasons Predis do not support them globally anymore, but the
actual classes are still shipped within the library so that they can
be used to build custom stuff at a level lower than client (that is,
unless we decide to remove them for good before going stable).
2013-11-09 12:07:36 +01:00
Daniele Alessandri 9da1648145 Mostly useless tweak for iterators example. 2013-11-07 12:10:04 +01:00
Daniele Alessandri 5ad00774e1 Rename for the last time all the iterator classes.
We are experimenting with a new approach at naming classes using less
redundant names by leveraging the containing namespace. The PHP "use"
directive is not limited to class names but can be used to import the
whole namespace, which means you can do something like this:

  use Predis\Collection\Iterator;
  // ...
  foreach (new Iterator\Keyspace($client) as $key) {
  	// ...
  }

Alternatively you can always rely on "use ... as ..." to import one of
the classes by giving it a more meaningful name in the context of the
root namespace:

  use Predis\Collection\Iterator\Keyspace as KeyspaceIterator;
  // ...
  foreach (new KeyspaceIterator($client) as $key) {
  	// ...
  }

In this specific case we chose to apply the -Key postfix to classes
iterating Redis keys to be more explicit about the fact that those
iterators does not work on local in-memory collections, but fetch
items from a key stored on a remote Redis server.
2013-11-07 12:09:59 +01:00
Daniele Alessandri df2c9eb7ff Move Redis collections iterators in a different namespace.
The base iterator class is now known as RedisCollectionIterator and
we've also renamed a few methods to make their naming more generic.
2013-11-06 16:19:12 +01:00
Daniele Alessandri 9866500ad6 Add example of iterators based on the various SCAN commands. 2013-11-03 15:05:05 +01:00
Daniele Alessandri 8533dbdb0b Deprecate Client::pubSub() in favor of Client::pubSubLoop().
Client::pubSub() still works like usual by returning a new pub/sub
context, but it is now considered an alias of Client::pubSubLoop().

This change is necessary in preparation for the next major version
of Predis where Client::pubSub() will be used for the new PUBSUB
command introduced in Redis 2.8.
2013-11-02 18:19:32 +01:00
Daniele Alessandri 3e125c964c Implement Predis\Session\SessionHandler.
This class makes it easy to use Predis to store PHP sessions on Redis.

NOTE: requires PHP >= 5.4.0 or a polyfill for PHP's SessionHandlerInterface.
2013-02-02 15:14:06 +01:00
Daniele Alessandri 0efcbb7992 Add a way to get the default value of an option from options.
It is not possible to get the default value of a client option using
either its name or instance:

  $options = array(
    'profile' => function ($options, $option) {
      // instance of Predis\Option\OptionInterface
      $profile = $options->getDefault($option);

      // string representing an option handled by $options,
      // returns NULL if the specified name is not handled.
      $profile = $options->getDefault('profile');

      return $profile;
    },
  );

This addition makes it less awkward to get the default value of an
option, especially when not in the context of a callable option
initializer.
2013-02-02 10:30:53 +01:00
Daniele Alessandri 732d7f96d1 Extract a strategy class from the replication connection. 2012-09-12 13:09:52 +02:00
Daniele Alessandri 576163724c Add an example for multibulk reply iterators.
[ci skip]
2012-08-21 18:10:49 +02:00
Daniele Alessandri e54bc31212 Create Predis\Cluster namespace and move related classes / interfaces. 2012-07-30 20:10:14 +02:00
Daniele Alessandri 7683f97ff2 Move the hash generator inside the command hash strategy class.
This should make things a tiny bit faster (we are speaking about micro
optimizations anyway) but more  importantly it results in a better
encapsulation.
2012-07-30 15:42:45 +02:00
Daniele Alessandri 55a3fd65a2 More code styling changes. 2012-07-27 12:23:25 +02:00
Daniele Alessandri 6c732c737b Order "use" directives by namespace depth and name.
This is not really useful per se, but at least we use a fixed rule.
2012-07-26 23:04:20 +02:00
Daniele Alessandri 559853bdd5 Move some classes and interfaces in other namespaces. 2012-07-26 22:37:31 +02:00
Daniele Alessandri ca7bd8149f Scripting abstraction can use negatives to calculate number of keys.
With a negative number Predis will count from the end of the arguments list
to calculate the actual number of keys that will be interpreted as elements
for `KEYS` by the underlying `EVAL` command.
2012-04-25 11:35:06 +02:00
Daniele Alessandri 9426d78b90 Fix example for custom distribution strategy.
See ISSUE #63 for details.
2012-04-13 11:37:03 +02:00
Daniele Alessandri dc14c29676 Rename certain namespaces, interfaces and classes.
Now we follow a Symfony2-like naming convention for namespaces, interfaces
and classes sticking with one clear rule.

- Renamed namespaces:

  - Predis\Network
  - Predis\Profiles
  - Predis\Iterators
  - Predis\Options
  - Predis\Commands
  - Predis\Commands\Processors

- Renamed interfaces:

  - Predis\IReplyObject
  - Predis\IRedisServerError
  - Predis\IConnectionFactory
  - Predis\IConnectionParameters
  - Predis\Options\IOption
  - Predis\Options\IClientOptions
  - Predis\Profile\IServerProfile
  - Predis\Pipeline\IPipelineExecutor
  - Predis\Distribution\INodeKeyGenerator
  - Predis\Distribution\IDistributionStrategy
  - Predis\Protocol\IProtocolProcessor
  - Predis\Protocol\IResponseReader
  - Predis\Protocol\IResponseHandler
  - Predis\Protocol\ICommandSerializer
  - Predis\Protocol\IComposableProtocolProcessor
  - Predis\Network\IConnection
  - Predis\Network\IConnectionSingle
  - Predis\Network\IConnectionComposable
  - Predis\Network\IConnectionCluster
  - Predis\Network\IConnectionReplication
  - Predis\Commands\ICommand
  - Predis\Commands\IPrefixable
  - Predis\Command\Processor\ICommandProcessor
  - Predis\Command\Processor\ICommandProcessorChain
  - Predis\Command\Processor\IProcessingSupport

- Renamed Classes:

  - Predis\Commands\Command
  - Predis\Network\ConnectionBase

- Classes moved to different namespaces:

  - Predis\MonitorContext

Meh
2012-01-31 18:19:18 +01:00
Daniele Alessandri 626520b836 Add specific server profile alias for Redis 2.6. 2012-01-14 13:01:38 +01:00
Daniele Alessandri 39a9fc2ddd Add a new example for complex replication configuration. 2011-12-27 12:34:44 +01:00
Daniele Alessandri 22f1aafae8 Fix example of replication. 2011-12-21 21:41:51 +01:00
Daniele Alessandri 466c666547 Add example for master / slave replication. 2011-12-21 21:01:48 +01:00
Daniele Alessandri dc9bd4e3a3 Add notice in the example of servers-side scripting with Lua. 2011-12-11 12:41:38 +01:00
Daniele Alessandri 371ac91777 [tests] Rewrite the whole test suite to allow more granular testing.
Fix also a few bugs found while rewriting the test suite.

In order to be able to run integration tests, the test suite requires
a version of Redis >= 2.4.0.

The units have been splitted into several different groups using
PHPUnit @group annotation to allow developers to enable, disable
and combine certain types of tests. The available groups are:

  - disconnected: can run without a Redis server online
  - connected: active connection to a Redis server is required
  - commands: test dedicated to a specific Redis command
  - slow: performs operations that can slow down execution;

A list of the available groups can be obtained by running

  phpunit --list-groups

Groups of tests can be disabled or enabled via the XML configuration
file or the standard command-line test runner. Please note that due
to a bug in PHPUnit, older versions ignore the --group option when
the group is excluded in the XML configuration file. Please refer to
http://github.com/sebastianbergmann/phpunit/issues/320 for details

Integration tests in the @connected group check if the command being
tested is defined in the selected server profile (see the value of
the TEST_SERVER_VERSION constant in phpunit.xml). If the command is
not defined in the target server profile, the integration test is
automatically marked as skipped.

We also provide an helper script in the bin directory that can be
used to automatically generate a file with the scheleton of a test
case for a Redis command by specifying the name of the class in the
Predis\Commands namespace. For example, to generate a test case for
SET (represented by the Predis\Commands\StringSet class):

  ./bin/generate-command-test.php --class=StringSet

The realm of a command is automatically inferred from the name of the
class, but it can be set using the --realm option.
2011-12-10 15:26:00 +01:00
Daniele Alessandri a894f470bd Add an "autoload.php" utility script for autoloading in examples and tests. 2011-11-28 10:19:11 +01:00
Daniele Alessandri 4882e23319 Move Publish/Subscribe related classes to the Predis\PubSub namespace. 2011-11-28 10:01:21 +01:00