NOTE: this specific test fails at random without any apparent reason
when executed on our CI environments and these failures are not tied
to a particular version of PHP or Redis. It is most likely some weird
timing issue on busy systems as it is really rare to get it triggered
locally. The chances it is a bug in the library are pretty low so for
now we just mark this test skipped on our CI environments (but still
enabled for local test runs) and "debug" this issue using a separate
branch to avoid having spurious failures on main development branches
which is utterly annoying.
We will restore this test on CI environments as soon as we understand
what is the reason behind its random failures.
These failures are random and rarely reproducible on a local development
environment but sometimes they affect the success of a test run and it's
annoying. I think it is just a weird timing issue on busy hosts so let's
try with a couple of simple usleep() after SUBSCRIBE and PUBLISH and see
if anything changes in the next few test runs.
Starting with Redis 6.0 and the introduction of Access Control Lists,
COMMAND INFO returns an additional array for each specified command in
the request with a list of the ACL categories associated to a command.
This change does not affect distribution but simply separates the two
concepts of connection ID (ip:port pair) and alias (value set via the
"alias" connection parameter), the method getConnectionByAlias() has
been added to reflect this change.
The method getConnectionBySlot() has also been added.
When using replication backends, now the role of a connection is not
defined by its alias but by the new connection parameter "role" that
can be set to "master", "slave" and (for redis-sentinel) "sentinel".
This also led to a redesign of how connections can be retrieved from
replication backends: the method getConnectionById() now retrieves a
connection only by its ID (ip:port pair), to get a connection by its
alias there is the new method getConnectionByAlias(). This method is
not supported by the redis-sentinel backend due to its dynamic nature
(connections are retrieved and initialized at runtime from sentinels)
but it is still possible to get a single connection from the pool by
using its ID. It is also possible to retrive a connection by its role
using the method getConnectionByRole().
NOTE: the "role" parameter is an hint for the internals of aggregate
connection backends so it is still possible that the actual role of
a connection changes during the execution of a script (e.g. a slave
gets promoted to the role of master): in this case the parameters of
that connection will not be changed as they are immutable, but the
method getConnectionByRole() will return the appropriate connection.
Predis\Client::getClientBy() has been updated with the addition of
"role" and "alias" as supported selectors.
In addition to that, the methods askSlotsMap() and buildSlotsMap() of
the redis-cluster connection backend have been renamed respectively
to askSlotMap() and buildSlotMap().
By default Predis chooses automatically which hash generator to use:
if a suitable version of ext-phpiredis is loaded (that is, a version
that implements the phpiredis_utils_crc16() function) it uses the new
Predis\Cluster\Hash\PhpiredisCRC16 generator, otherwise it falls back
to the usual pure-PHP Predis\Cluster\Hash\CRC16 generator.
Generating the hash of a string of 10 bytes is 10 times faster than
the equivalent pure-PHP implementation of CRC16 (PHP 7.0.7).
This generator requires a version of phpiredis that implements the
function "phpiredis_utils_crc16()".
This method improves the previous one, which worked only by picking a
connection by ID, allowing users to specify a selector type among the
following ones: "id", "key", "slot", "command". These selectors are
expanded internally to methods, invoked against the connection object
in use by the client, that follow the getConnectionByXXX() convention
already in use through the library:
id => getConnectionById()
key => getConnectionByKey()
slot => getConnectionBySlot()
command => getConnectionByCommand()
The underlying connection does not necessarily need to implement the
aggregate connection interface as the client relies on a duck-typing
approach by using method_exists().