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.
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.
We now have a base test case class for Predis (namely PredisTestCase)
grouping various commonly used utility methods shared by all of the
tests in the suite, greatly improving reusability.
The reason for this change is to support the upcoming redis-cluster since
it has different behaviors compared to the client-side cluster implementation
provided by Predis. For example redis-cluster will not support key tags or
certain operations currently available with our client-side implementation.