mirror of
https://github.com/predis/predis.git
synced 2026-08-30 12:15:03 +00:00
Implement transparent auto-retry of commands upon server failure.
By default, when the current server dies while executing a command Predis asks for a new configuration to one of the sentinels and re-issues the same command. This behavior can be disabled calling SentinelReplication::setAutomaticRetry().
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Predis\Connection\Aggregate;
|
||||
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\RawCommand;
|
||||
use Predis\Connection\ConnectionException;
|
||||
use Predis\Connection\Factory as ConnectionFactory;
|
||||
@@ -54,6 +55,11 @@ class SentinelReplication extends MasterSlaveReplication
|
||||
*/
|
||||
protected $sentinelTimeout = 0.100;
|
||||
|
||||
/**
|
||||
* Flag for automatic retries of commands upon server failure.
|
||||
*/
|
||||
protected $autoRetry = true;
|
||||
|
||||
/**
|
||||
* @param array $sentinels Sentinel servers connection parameters.
|
||||
* @param string $service Name of the service for autodiscovery.
|
||||
@@ -86,6 +92,16 @@ class SentinelReplication extends MasterSlaveReplication
|
||||
$this->sentinelTimeout = (float) $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set automatic retries of commands upon server failure.
|
||||
*
|
||||
* @param bool $retry Retry value.
|
||||
*/
|
||||
public function setAutomaticRetry($retry)
|
||||
{
|
||||
$this->autoRetry = (bool) $retry;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -245,4 +261,57 @@ class SentinelReplication extends MasterSlaveReplication
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retries the execution of a command upon server failure after asking a new
|
||||
* configuration to one of the sentinels.
|
||||
*
|
||||
* @param string $method Actual method.
|
||||
* @param CommandInterface $command Command instance.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function retryCommandOnFailure($method, $command)
|
||||
{
|
||||
SENTINEL_RETRY: {
|
||||
try {
|
||||
$response = parent::$method($command);
|
||||
} catch (ConnectionException $exception) {
|
||||
if (!$this->autoRetry) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$exception->getConnection()->disconnect();
|
||||
$this->querySentinel();
|
||||
|
||||
goto SENTINEL_RETRY;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function writeRequest(CommandInterface $command)
|
||||
{
|
||||
$this->retryCommandOnFailure(__FUNCTION__, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function readResponse(CommandInterface $command)
|
||||
{
|
||||
return $this->retryCommandOnFailure(__FUNCTION__, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function executeCommand(CommandInterface $command)
|
||||
{
|
||||
return $this->retryCommandOnFailure(__FUNCTION__, $command);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user