mirror of
https://github.com/predis/predis.git
synced 2026-09-11 02:46:59 +00:00
Implement ROLE for proper redis-sentinel support.
Once the client discovers the address of the master or a slave instance, it must connect to that node and issue a ROLE command to verify that its role still matches what the client got from the sentinel server.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Predis\Connection\Aggregate;
|
||||
|
||||
use Predis\CommunicationException;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\RawCommand;
|
||||
use Predis\Connection\ConnectionException;
|
||||
@@ -19,6 +20,7 @@ use Predis\Connection\FactoryInterface as ConnectionFactoryInterface;
|
||||
use Predis\Connection\NodeConnectionInterface;
|
||||
use Predis\Connection\Parameters;
|
||||
use Predis\Replication\ReplicationStrategy;
|
||||
use Predis\Replication\RoleException;
|
||||
use Predis\Response\ErrorInterface as ErrorResponseInterface;
|
||||
use Predis\Response\ServerException;
|
||||
|
||||
@@ -324,6 +326,28 @@ class SentinelReplication extends MasterSlaveReplication
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConnection(CommandInterface $command)
|
||||
{
|
||||
$connection = parent::getConnection($command);
|
||||
|
||||
if (!$connection->isConnected()) {
|
||||
$role = $connection->executeCommand(RawCommand::create('ROLE'));
|
||||
|
||||
if ($connection === $this->master && $role[0] !== 'master') {
|
||||
throw new RoleException($connection, "Expected master but got $role[0] [$connection]");
|
||||
}
|
||||
|
||||
if ($connection !== $this->master && $role[0] !== 'slave') {
|
||||
throw new RoleException($connection, "Expected slave but got $role[0] [$connection]");
|
||||
}
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retries the execution of a command upon server failure after asking a new
|
||||
* configuration to one of the sentinels.
|
||||
@@ -340,7 +364,7 @@ class SentinelReplication extends MasterSlaveReplication
|
||||
SENTINEL_RETRY: {
|
||||
try {
|
||||
$response = parent::$method($command);
|
||||
} catch (ConnectionException $exception) {
|
||||
} catch (CommunicationException $exception) {
|
||||
if ($retries == $this->retryLimit) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Replication;
|
||||
|
||||
use Predis\CommunicationException;
|
||||
|
||||
/**
|
||||
* Exception class that identifies a role mismatch when connecting to node
|
||||
* managed by redis-sentinel.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class RoleException extends CommunicationException
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user