Commit Graph

113 Commits

Author SHA1 Message Date
Daniele Alessandri b0f955b437 Fix phpdocs.
[ci skip]
2013-11-12 19:49:55 +01:00
Daniele Alessandri a1c7889584 Add option "aggregate" to customize multiple connections aggregation.
This option must return a callable object that is used to override how
the client aggregates connections when passing an array of parameters
to its constructor.

When specified, this option overrides both "cluster" and "replication"
as it allows to make use of your own code to aggregate multiple nodes.

This is, for example, how you can mimic the standard initialization of
a cluster that relies on client-side sharding:

  $parameters = ['tcp://127.0.0.1:6380', 'tcp://127.0.0.1:6381'];

  $options = [
    'aggregate' => function () {
      return function ($parameters, $options) {
          $connection = new Predis\Connection\PredisCluster();
          $options->connections->aggregate($connection, $parameters);

          return $connection;
      };
    },
  ];

  $client = new Predis\Client($parameters, $options);

When invoked by the client, the specified callable must always return
a Predis\Connection\ConnectionInterface instance or the client will
throw an UnexpectedValueException.
2013-11-12 12:31:45 +01:00
Daniele Alessandri acd29ec076 Slightly change interface for connection factories. 2013-11-11 18:24:20 +01:00
Daniele Alessandri 3c6389f4dd Rework how connection parameters are handled.
These changes do not affect the actual functionalities of the client,
but make the code more explicit and less error-prone.
2013-11-11 18:17:09 +01:00
Daniele Alessandri 1d53f8a988 Minor code styling changes. 2013-11-11 15:59:21 +01:00
Daniele Alessandri dd679661dd Address #133 by reusing our own methods.
The main reason behind that code duplication was performance related
as we tried to reduce method calls when possible, even at the cost of
falling into the realm of early optimizations. Apparently we just lose
~400 req/sec on a 21000 req/sec basis ("SET foo bar") using PHP 5.5.3
(packaged by Ubuntu 13.10) on an Intel Q6600, so we will most likely
stick with this change for the sake of best practices.
2013-11-11 15:49:16 +01:00
Daniele Alessandri 31e08f0d5d Tweak phpdocs. 2013-11-11 12:29:43 +01:00
Daniele Alessandri cdb91284f1 Clean up ugly code bits. 2013-11-10 12:30:24 +01:00
Daniele Alessandri 38c7697881 Remove useless method. 2013-11-10 12:27:15 +01:00
Daniele Alessandri b45ba55f46 Switch to protected visibility for some members of Predis\Client.
The "profile" member is actually used for caching purposes as fetching
its value from the options instance would add noticeable overhead in a
part of the client where every bit of optimization matters, for this
we decided to keep it private.
2013-11-10 12:20:20 +01:00
Daniele Alessandri b50b90aa66 Rename method. 2013-11-10 12:17:58 +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 f066356858 Slightly change the internal context factory method of Predis\Client. 2013-11-09 19:16:09 +01:00
Daniele Alessandri 7649533141 Remove some obsoleted or useless methods from Predis\Client. 2013-11-09 19:07:24 +01:00
Daniele Alessandri 089b972def Merge branch 'v0.9/client-options' 2013-11-08 12:08:26 +01:00
Daniele Alessandri b1ebc8df2f Reimplement from scratch client configuration.
This commit is a complete rewrite of the classes previously contained
in the Predis\Option namespace aimed at lowering the initialization
overhead while bringing in more consistency. The overall idea is still
the same with a mini DI container, Predis\Configuration\Options, which
carries options with values that can be initialized lazily.

The first difference with our previous implementation is that now even
user-defined options can be initialized lazily, everything needed is
an object responding to the __invoke() magic method such as a closure.
Other kind of callable arguments (strings, arrays) will be treated as
plain values. The only drawback is that we cannot pass any instance of
classes implementing __invoke() as an option value, but considered the
limited scope of our use case we can say it's more of an acceptable
compromise. Callbacks used for lazy initialization will receive two
arguments upon invokation:

  - The current instance of Predis\Configuration\Option ($options)
  - A string containing the name of the option ($option)

This is an example in actual code:

  $options = new Predis\Configuration\Options([
    'exceptions' => true,
    'profile' => '2.8',
    'distributor' => function () {
      return new Predis\Cluster\Distribution\KetamaPureRing();
    },
    'cluster' => function ($options) {
      $distr    = $options->distributor;
      $strategy = new Predis\Cluster\PredisClusterHashStrategy($distr);
      $cluster  = new Predis\Connection\PredisCluster();

      return $cluster;
    },
    'connections' => function ($options, $option) {
      $factory = $options->getDefault($option);
      $factory->define('tcp', 'Predis\Connection\PhpiredisConnection');

      return $factory;
    },
  ]);

As you can see there's very little difference compared to before in
the actual usage as most changes are under the hood. Some options such
as "exceptions" and "replication" can now correctly parse bool values
from strings (so the string "false" is not evaluated as boolean true).

While options were initially conceived to configure the client and its
behavior, the concept has matured and it's perfectly fine to consider
the use of Predis\Configuration\Options to propagate configurations to
inner parts of the library.
2013-11-08 12:08:11 +01:00
Daniele Alessandri 153758019c Diverging from the v0.8 branch (current stable).
This commit marks the start of works for the next major release of
Predis which will bring various breaking changes needed to polish the
internal design making the library even more flexible to use or extend
and, more importantly, almost stable in terms of API.

The Redis commands API exposed by Predis\Client is not going to change
much if not at all which is a good news. The most immediate changes
affecting developers will involve the renaming of a few namespaces and
classes, the removal of some previously deprecated classes and methods
and some tweaks to the current abstractions.

Right now the plan is to have a fast paced development to release this
version as soon as possible, ideally a few weeks later than Redis 2.8,
then wait to see the final definition of redis-cluster so that we can
tweak our code if needed and finally hit the v1.0.0 milestone with as
few changes as possible. Furthermore, v1.x will most likely be the
last version of Predis supporting PHP 5.3 as we will start migrating
to PHP 5.4 (or even 5.5) with v2.x, which is not going to happen soon
anyway.
2013-11-08 11:17:50 +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 98aacd8d9a Back to development for the next patch release. 2013-11-02 18:19:31 +01:00
Daniele Alessandri cb18d67b6a Update CHANGELOG and bump VERSION. 2013-07-27 11:13:54 +02:00
Alexandru Patranescu 2d2930d24f some PHPDoc fixes in lib
and removed some unused imports also
2013-06-03 00:06:41 +03:00
Daniele Alessandri 5a735aa670 Back to development for the next patch release. 2013-03-16 12:11:37 +01:00
Daniele Alessandri 8c0498a893 Bump VERSION and update CHANGELOG. 2013-02-18 15:03:45 +01:00
Daniele Alessandri 8cbcb09c4c Remove a few unnecessary strict comparisons. 2013-02-16 17:05:12 +01:00
Daniele Alessandri 2781bd780f Fetch connection factory directly from client options. 2013-02-16 14:36:04 +01:00
Daniele Alessandri c38376dcc4 Accepts callable as first argument of Predis\Client::__construct().
Users can then use callables to wrap the creation and initialization
of the underlying connection with custom strategies:
2013-02-15 11:36:19 +01:00
Daniele Alessandri 9e0fe7bdc7 Back to development for the next patch release.
Forgot to do that prior to merge, my bad.

[ci skip]
2013-02-08 14:54:53 +01:00
Daniele Alessandri aa1b070f9b Bump VERSION and update CHANGELOG. 2013-02-03 13:59:55 +01:00
Daniele Alessandri 7173f0c80c Get back to development. 2013-01-29 11:55:47 +01:00
Daniele Alessandri 495e3c6f8a Bump VERSION and update CHANGELOG.
[ci skip]
2013-01-19 11:18:58 +01:00
Daniele Alessandri 9901233fa1 Instantiate the current class when subclassing Client.
Previously the getClientFor() method in a subclass of Predis\Client
returned an instance of Predis\Client instead of a new instance of
the subclass. The new behaviour is more correct.
2012-12-24 14:50:07 +01:00
Daniele Alessandri bfd96b15dc Fix response parsing with scripted commands after -NOSCRIPT.
This commit fixes issue #94.
2012-12-12 14:28:06 +01:00
Daniele Alessandri 0b09d2c359 Back to development for the next patch release. 2012-11-03 15:16:01 +01:00
Daniele Alessandri 0a622aee31 Bump VERSION and update CHANGELOG.
Guess what time is it? Yeah, once again... it is release time!
2012-10-23 01:46:05 +02:00
Ondrej -onovy- Novy 6cd1f03834 Fixed typos. 2012-09-18 17:43:29 +02:00
Daniele Alessandri 1b9e10bdd8 Move command response parsing to the client class.
Connection classes should just handle, convert and return simple Redis
types while parsing and transforming structured replies should be done
by consumers (see Predis\Client or Predis\Transaction\MultiExecContext).

This actually makes more sense considering that parsing a complex response
with the associated command parser may require different actions. As an
example, the result of EXEC is a multibulk that holds the actual responses,
so we really need to parse each one of its elements and we should also
make sure that iterable multibulks are consumed. We already did that
previously, but it was weird knowing that command parsers were applied
by the connection class.

This also moves some duplicated logic away from each connection class
implementation which is a nice bonus.
2012-09-04 14:53:05 +02:00
Daniele Alessandri a6e1ac11d0 Implement separate Predis\Client::getConnectionById().
This method is not part of Predis\ClientInterface because it is being
considered mostly an helper / utility method.
2012-08-24 12:07:56 +02:00
Daniele Alessandri 8567b05459 Specify the server profile in constructor of the connection factory.
When no server profile is specified, the connection factory will not push
any initialization command to the newly created connection object.

This change is mainly useful when using redis-cluster and also makes it
possible to easily inject commands such as "SCRIPT LOAD" at initialization
time by grouping everything into one common place simply by extending the
connection factory class.
2012-08-19 13:57:58 +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 0e8d978348 Minor code styling changes in client class.
[ci skip]
2012-07-26 15:18:09 +02:00
Daniele Alessandri 469f3cc68b Do not accept string or Predis\Profile\ServerProfileInstance in constructor.
To specify a server profile you can just set the "prefix" option in the
client options array passed to the constructor of Predis\Client.
2012-07-26 14:36:01 +02:00
Daniele Alessandri 81be513eaa Change signature of Predis\Pipeline\PipelineContext constructor.
Now the second argument is a Predis\Pipeline\PipelineExecutorInterface.
2012-07-26 11:33:24 +02:00
Daniele Alessandri c3cafaa9a6 Remove useless helpers. 2012-07-25 21:18:58 +02:00
Daniele Alessandri 78360ea27b Set raw arguments when switching from scripted command to EVAL. 2012-04-28 18:04:54 +02:00
Daniele Alessandri 2d0b30dac5 Client handles -NOSCRIPT falling back to EVAL for scripted commands.
Now Predis\Command\ScriptedCommand uses EVALSHA instead of EVAL internally
so that performances should be better since the client do not resend the
Lua script body on each call.

Plain EVALSHA commands are not affected and will return or throw the error.
2012-04-28 08:56:11 +02:00
Daniele Alessandri c36e6fd900 Pass also the command that generated the server error. 2012-04-27 23:59:51 +02:00
Daniele Alessandri 41c29bed4e Change how Redis errors such as -ERR replies generates exceptions.
The "throw_errors" connection parameter has been removed and replaced by the
new "exceptions" client option since exceptions on -ERR replies returned by
Redis are not generated by connection classes anymore but are thrown by the
client class and other abstractions such as pipeline contexts.

This change does not affect much people using the Predis\Client class (aside
from the different configuration) but gives much more flexibility to those
building their own pieces of code around the internal classes of Predis.
2012-04-27 23:29:41 +02:00
Daniele Alessandri 51d0b58cd3 Add new interfaces used to abstract the main client class and contexts.
Now developers can pass a client object or an executable context (see
Predis\Transaction\MultiExecContext or Predis\Pipeline\PipelineContext)
interchangeably as parameters to their methods using the new interface
Predis\BasicCliantInterface.

These new interfaces will also allow us to easily create new client
classes aside from the standard Predis\Client one.
2012-03-18 11:05:33 +01:00