These parameters are applied only to connections being created on the
fly when not part of the current pool. This condition usually happens
upon -MOVE or -ASK responses returned by Redis to redirect client to
different nodes.
Only named arrays are explicitly accepted now, but the old behaviour
of creating a connection parameters instance out of an URI string or
a named array is still available using the "create()" static method.
$array = ['host' => '127.0.0.1', 'timeout' => 1];
$uri = 'tcp://127.0.0.1?timeout=1';
$parameters = new ConnectionParameters($array); // Arrays only
$parameters = ConnectionParameters::create($array); // Arrays OK
$parameters = ConnectionParameters::create($uri); // Strings OK
The purpose of the change is to have a more concise constructor with a
well defined signature.
List of changes:
- The cluster connection can be initialized with a partial list of
nodes, the full slots map will be fetched from Redis itself using
the CLUSTER NODES command.
- The slots map can be optionally retrieved from Redis if the server
returns a -MOVE response, otherwise only the interested slot will
be permanently reassigned to the new target node.
- $cluster->connect() connects to a random connection in the pool
instead of forcing the connect operation on all the connections.
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.
This optimization is mostly useful since connection parameters can be
instantiated more than one time in a script when using clustering or
replication.
A profile is not needed to create instances of basic initialization
commands such as AUTH (authentication) and SELECT (database selection)
since they do not need prefixing and other stuff.
If needed, developers can still extend the base connection factory to
make it use a server profile and configure the client to use it using
options.
When sending raw commands their arguments are not filtered, responses
are not parsed and key prefixes are not applied. The client also does
not throw any exception on Redis errors regardless of its settings.
The first parameter takes the raw arguments of the command (included
its identifier) as defined by the Redis documentation while the second
optional parameter is always populated by reference to indicate when
Redis actually returned an error response.
$client->raw(['PING']); // "PONG"
$client->raw(['SET','foo','bar']); // "OK"
$client->raw(['GET','foo'], $err); // "bar", $err=FALSE
$client->raw(['LPUSH','foo',1], $err); // "WRONGTYPE...", $err=TRUE
Internally, this method creates instances of Predis\Command\RawCommand
that get passed to the underlying connection instance for execution as
if they were usual commands defined by Predis.
Raw commands work in both cluster and replication scenarios since they
are recognized by their command ID, but key prefixing is not supported
since it is done by the profile instance when instantiating commands.
We must always execute ASKING on the connection identified by the -ASK
response before executing the actual command because not doing so will
break the cluster specifications while redis-cluster is performing a
resharding operation.
By raw we mean that input arguments are not filtered and responses are
not parsed, which means arguments must follow the command signature as
defined by Redis and complex responses are left untouched.
When instantiating an instance of `Predis\Command\RawCommand` you must
pass at least the command ID. You can pass further arguments in the
array or you can just set them later with `RawCommand::setArguments()`
but you cannot modify the command ID once instantiated.
$command = new Predis\Command\RawCommand(['SET', 'foo', 'bar']);
$response = $client->executeCommand($command);
While higher level abstractions built upon `Predis\Client` should just
use commands created by the profile in use, inner parts of the library
might use raw commands to provide certain functionalities making sure
that input and output of commands are always consistent, independent
of the profile.
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".
It was too broad in concept and not really that useful, so for now we
assume that only our base Predis\Profile\RedisProfile class can handle
command processing and we will decide later if we want to add a couple
of more methods to Predis\Profile\ProfileInterface.
While command classes define how the client should filter arguments or
parse responses, key prefixing depends on the actual command signature
as defined by Redis so it really is something that should be handled
separately as the norm.
Developers can define new handlers or override existing ones, but they
can still define the key prefixing logic inside their command classes
by implementing Predis\Command\PrefixableCommandInterface: the key
prefix processor will just use that by overriding any defined handler.
In this method we can put the logic needed to prepare the connection
right before sending the queued commands to the server (e.g. switching
to the master server when connected in replication mode).
Commands such as MULTI, EXEC, DISCARD, WATCH and UNWATCH disregard the
the "exceptions" client option and always result in an exception being
thrown on error responses even when the client is configured to return
those errors ("exceptions" set to FALSE).
We also changed some options for this class, the accepted ones are:
- "keys": string or array of strings for automatic WATCH.
- "cas": sets the check-and-set mode.
- "retry": number of attempts before giving up aborted transactions.
- "exceptions": sets whether exceptions should be thrown on error
responses (overrides the "exceptions" client option).
The "on_retry" option has been removed.
The Predis\Transaction\MultiExecState class is actually quite dummy as
it does not work as a finite-state machine, but is used to track state
using flags. It basically replicates the same behaviour of when it was
part of the Predis\Transaction\MultiExec code and it will do for now.
Only two options available for now, used to specify which kind of
pipeline object the client should use or return:
- "atomic": returns a pipeline wrapped in a MULTI / EXEC transaction
(class: Predis\Pipeline\Atomic).
- "fire-and-forget": returns a pipeline that does not read back
responses from the server (class: Predis\Pipeline\FireAndForget).
We might add more options in the future.
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.