Send ASKING command when redis-cluster returns a -ASK response.

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.
This commit is contained in:
Daniele Alessandri
2013-11-30 17:23:04 +01:00
parent 7f690cb62e
commit 5d7f297110
2 changed files with 25 additions and 4 deletions
+6 -2
View File
@@ -15,6 +15,7 @@ use Predis\ClientException;
use Predis\NotSupportedException;
use Predis\Cluster;
use Predis\Command\CommandInterface;
use Predis\Command\RawCommand;
use Predis\Response;
/**
@@ -279,10 +280,13 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
switch ($request) {
case 'MOVED':
$this->move($connection, $slot);
return $this->executeCommand($command);
$response = $this->executeCommand($command);
return $response;
case 'ASK':
return $connection->executeCommand($command);
$connection->executeCommand(RawCommand::create('ASKING'));
$response = $connection->executeCommand($command);
return $response;
default:
throw new ClientException("Unexpected request type for a move request: $request");
+19 -2
View File
@@ -434,7 +434,10 @@ class RedisClusterTest extends StandardTestCase
->will($this->onConsecutiveCalls($askResponse, 'foobar'));
$connection2 = $this->getMockConnection('tcp://127.0.0.1:6380');
$connection2->expects($this->exactly(1))
$connection2->expects($this->at(2))
->method('executeCommand')
->with($this->isRedisCommand('ASKING'));
$connection2->expects($this->at(3))
->method('executeCommand')
->with($command)
->will($this->returnValue('foobar'));
@@ -471,7 +474,10 @@ class RedisClusterTest extends StandardTestCase
->method('executeCommand');
$connection3 = $this->getMockConnection('tcp://127.0.0.1:6381');
$connection3->expects($this->once())
$connection3->expects($this->at(0))
->method('executeCommand')
->with($this->isRedisCommand('ASKING'));
$connection3->expects($this->at(1))
->method('executeCommand')
->with($command)
->will($this->returnValue('foobar'));
@@ -605,6 +611,17 @@ class RedisClusterTest extends StandardTestCase
// ---- HELPER METHODS ------------------------------------------------ //
// ******************************************************************** //
/**
* Asserts that two arrays have the same values, even if with different order.
*
* @param string|CommandInterface $command Expected command or command ID.
* @param array $arguments Expected command arguments.
*/
protected function isRedisCommand($command = null, array $arguments = null)
{
return new \RedisCommandConstraint($command, $arguments);
}
/**
* Returns a base mocked connection from Predis\Connection\SingleConnectionInterface.
*