mirror of
https://github.com/predis/predis.git
synced 2026-09-05 15:42:31 +00:00
Improve handling of -MOVED and -ASK responses.
This change improves code reusing and simplifies the internals of our redis-cluster connection backend.
This commit is contained in:
@@ -19,7 +19,6 @@ use Predis\NotSupportedException;
|
||||
use Predis\Cluster\RedisStrategy as RedisClusterStrategy;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\RawCommand;
|
||||
use Predis\Protocol\ProtocolException;
|
||||
use Predis\Response\ErrorInterface as ErrorResponseInterface;
|
||||
|
||||
/**
|
||||
@@ -257,6 +256,26 @@ class RedisCluster implements ClusterConnectionInterface, IteratorAggregate, Cou
|
||||
return $nodes[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection instance from the given connection ID.
|
||||
*
|
||||
* @param string $connectionID Identifier for the connection.
|
||||
* @return SingleConnectionInterface
|
||||
*/
|
||||
protected function createConnection($connectionID)
|
||||
{
|
||||
$host = explode(':', $connectionID, 2);
|
||||
|
||||
$parameters = array_merge($this->defaultParameters, array(
|
||||
'host' => $host[0],
|
||||
'port' => $host[1],
|
||||
));
|
||||
|
||||
$connection = $this->connections->create($parameters);
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -298,13 +317,7 @@ class RedisCluster implements ClusterConnectionInterface, IteratorAggregate, Cou
|
||||
$connectionID = $this->guessNode($slot);
|
||||
|
||||
if (!$connection = $this->getConnectionById($connectionID)) {
|
||||
$host = explode(':', $connectionID, 2);
|
||||
$parameters = array_merge($this->defaultParameters, array(
|
||||
'host' => $host[0],
|
||||
'port' => $host[1],
|
||||
));
|
||||
|
||||
$connection = $this->connections->create($parameters);
|
||||
$connection = $this->createConnection($connectionID);
|
||||
$this->pool[$connectionID] = $connection;
|
||||
}
|
||||
|
||||
@@ -347,7 +360,7 @@ class RedisCluster implements ClusterConnectionInterface, IteratorAggregate, Cou
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles -ERR responses from Redis.
|
||||
* Handles -ERR responses returned by Redis.
|
||||
*
|
||||
* @param CommandInterface $command Command that generated the -ERR response.
|
||||
* @param ErrorResponseInterface $error Redis error response object.
|
||||
@@ -359,8 +372,10 @@ class RedisCluster implements ClusterConnectionInterface, IteratorAggregate, Cou
|
||||
|
||||
switch ($details[0]) {
|
||||
case 'MOVED':
|
||||
return $this->onMovedResponse($command, $details[1]);
|
||||
|
||||
case 'ASK':
|
||||
return $this->onMoveRequest($command, $details[0], $details[1]);
|
||||
return $this->onAskResponse($command, $details[1]);
|
||||
|
||||
default:
|
||||
return $error;
|
||||
@@ -368,51 +383,51 @@ class RedisCluster implements ClusterConnectionInterface, IteratorAggregate, Cou
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles -MOVED and -ASK responses by re-executing the command on the node
|
||||
* specified by the Redis response.
|
||||
* Handles -MOVED responses by executing again the command against the node
|
||||
* indicated by the Redis response.
|
||||
*
|
||||
* @param CommandInterface $command Command that generated the -MOVE or -ASK response.
|
||||
* @param string $request Type of request (either 'MOVED' or 'ASK').
|
||||
* @param string $details Parameters of the MOVED/ASK request.
|
||||
* @param CommandInterface $command Command that generated the -MOVED response.
|
||||
* @param string $details Parameters of the -MOVED response.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function onMoveRequest(CommandInterface $command, $request, $details)
|
||||
protected function onMovedResponse(CommandInterface $command, $details)
|
||||
{
|
||||
list($slot, $host) = explode(' ', $details, 2);
|
||||
$connection = $this->getConnectionById($host);
|
||||
list($slot, $connectionID) = explode(' ', $details, 2);
|
||||
|
||||
if (!$connection) {
|
||||
$host = explode(':', $host, 2);
|
||||
$parameters = array_merge($this->defaultParameters, array(
|
||||
'host' => $host[0],
|
||||
'port' => $host[1],
|
||||
));
|
||||
|
||||
$connection = $this->connections->create($parameters);
|
||||
if (!$connection = $this->getConnectionById($connectionID)) {
|
||||
$connection = $this->createConnection($connectionID);
|
||||
}
|
||||
|
||||
switch ($request) {
|
||||
case 'MOVED':
|
||||
if ($this->askClusterNodes) {
|
||||
$this->askClusterNodes();
|
||||
}
|
||||
|
||||
$this->move($connection, $slot);
|
||||
$response = $this->executeCommand($command);
|
||||
|
||||
return $response;
|
||||
|
||||
case 'ASK':
|
||||
$connection->executeCommand(RawCommand::create('ASKING'));
|
||||
$response = $connection->executeCommand($command);
|
||||
|
||||
return $response;
|
||||
|
||||
default:
|
||||
throw new ProtocolException(
|
||||
"Unexpected request type for a move request: $request."
|
||||
);
|
||||
if ($this->askClusterNodes) {
|
||||
$this->askClusterNodes();
|
||||
}
|
||||
|
||||
$this->move($connection, $slot);
|
||||
$response = $this->executeCommand($command);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles -ASK responses by executing again the command against the node
|
||||
* indicated by the Redis response.
|
||||
*
|
||||
* @param CommandInterface $command Command that generated the -ASK response.
|
||||
* @param string $details Parameters of the -ASK response.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function onAskResponse(CommandInterface $command, $details)
|
||||
{
|
||||
list($slot, $connectionID) = explode(' ', $details, 2);
|
||||
|
||||
if (!$connection = $this->getConnectionById($connectionID)) {
|
||||
$connection = $this->createConnection($connectionID);
|
||||
}
|
||||
|
||||
$connection->executeCommand(RawCommand::create('ASKING'));
|
||||
$response = $connection->executeCommand($command);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user