예제 #1
0
 public function testThatFailoverIsInitiatedAndFailingCommandsAreRetried()
 {
     // we need a factory to create the clients
     $clientFactory = new PredisClientCreator();
     // we need an adapter for each sentinel client too!
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel1 = new Client('192.168.50.40', '26379', $clientAdapter);
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel2 = new Client('192.168.50.41', '26379', $clientAdapter);
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel3 = new Client('192.168.50.30', '26379', $clientAdapter);
     // configure how to back-off on reconnection attempts
     $backoffStrategy = new Incremental(500000, 2);
     $backoffStrategy->setMaxAttempts(10);
     // now we can start configuring the sentinel in the master discovery object
     $masterDiscovery = new MasterDiscovery('integrationtests');
     $masterDiscovery->setBackoffStrategy($backoffStrategy);
     $masterDiscovery->addSentinel($sentinel1);
     $masterDiscovery->addSentinel($sentinel2);
     $masterDiscovery->addSentinel($sentinel3);
     // configure the HAClient that we'll use to talk to the redis master as a proxy
     $HAClient = new HAClient($masterDiscovery);
     // simulate a segfault in 5s
     $this->debugSegfaultToMaster();
     for ($i = 1; $i <= 30; $i++) {
         $HAClient->incr(__METHOD__);
     }
     $this->assertEquals(30, $HAClient->get(__METHOD__), 'Test that all increment calls were executed');
 }
예제 #2
0
 /**
  * @return Client\ClientAdapter
  * @throws \PSRedis\Exception\ConfigurationError
  * @throws \PSRedis\Exception\ConnectionError
  */
 public function getMaster()
 {
     if (is_null($this->master)) {
         $this->master = $this->masterDiscovery->getMaster();
     }
     return $this->master;
 }
예제 #3
0
 /**
  * Proxies a call to a non-existing method in this object to the redis client
  *
  * @param $name
  * @param array $arguments
  * @return mixed
  */
 private function proxyFunctionCallToMaster($name, array $arguments)
 {
     if ($this->masterIsUnknown()) {
         $this->master = $this->masterDiscovery->getMaster();
     }
     return call_user_func_array(array($this->master, $name), $arguments);
 }
예제 #4
0
 public function addSentinels()
 {
     $clients = Config::get('database.redis.masters');
     foreach ($clients as $client) {
         $sentinel = App::make('PSRedis\\Client', [$client['host'], $client['port']]);
         $this->masterDiscovery->addSentinel($sentinel);
     }
 }
예제 #5
0
 public function testDiscoveryWithBackoffFailsWhenSentinelsStayOffline()
 {
     $this->setExpectedException('\\PSRedis\\Exception\\ConnectionError', 'All sentinels are unreachable');
     // disable sentinel on all nodes
     $this->disableSentinelAt('192.168.50.40');
     $this->disableSentinelAt('192.168.50.41');
     $this->disableSentinelAt('192.168.50.30');
     // we need a factory to create the clients
     $clientFactory = new PredisClientCreator();
     // we need an adapter for each sentinel client too!
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel1 = new Client('192.168.50.40', '26379', $clientAdapter);
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel2 = new Client('192.168.50.41', '26379', $clientAdapter);
     $clientAdapter = new PredisClientAdapter($clientFactory, Client::TYPE_SENTINEL);
     $sentinel3 = new Client('192.168.50.30', '26379', $clientAdapter);
     // now we can start discovering where the master is
     $masterDiscovery = new MasterDiscovery('integrationtests');
     $masterDiscovery->addSentinel($sentinel1);
     $masterDiscovery->addSentinel($sentinel2);
     $masterDiscovery->addSentinel($sentinel3);
     // configure a backoff strategy
     $incrementalBackoff = new Incremental(500, 1.5);
     $incrementalBackoff->setMaxAttempts(5);
     $masterDiscovery->setBackoffStrategy($incrementalBackoff);
     // try to discover the master
     $master = $masterDiscovery->getMaster();
 }
예제 #6
0
 /**
  * @param MasterDiscovery $masterDiscovery
  */
 private function configureBackoffStrategy(MasterDiscovery $masterDiscovery)
 {
     $backoffStrategy = new MasterDiscovery\BackoffStrategy\Incremental($this->backoffParameters['offset'], $this->backoffParameters['multiplier']);
     $backoffStrategy->setMaxAttempts($this->backoffParameters['maximum_attempts']);
     $masterDiscovery->setBackoffStrategy($backoffStrategy);
 }
예제 #7
0
 /**
  * @return MasterDiscovery
  */
 private function masterDiscovery()
 {
     $masterDiscovery = new MasterDiscovery($this->getMasterName());
     foreach ($this->getSentinels() as $sentinel) {
         $masterDiscovery->addSentinel($sentinel);
     }
     return $masterDiscovery;
 }
예제 #8
0
 /**
  * @group regression
  * @group issue-9
  */
 public function testThatABackoffStrategyIsResetWhenStartingTheMasterDiscovery()
 {
     $backoff = new Incremental(0, 1);
     $backoff->setMaxAttempts(2);
     $sentinel1 = $this->mockOfflineSentinel();
     $masterDiscovery = new MasterDiscovery('online-sentinel');
     $masterDiscovery->setBackoffStrategy($backoff);
     $masterDiscovery->addSentinel($sentinel1);
     try {
         $masterNode = $masterDiscovery->getMaster();
     } catch (ConnectionError $e) {
         // we expect this to fail as no sentinels are online
     }
     // add a sentinel that fails first, but succeeds after back-off (the bug, if present, will prevent reconnection of sentinels after backoff)
     $sentinel2 = $this->mockTemporaryOfflineSentinel();
     $masterDiscovery->addSentinel($sentinel2);
     // try to discover the master node
     $masterNode = $masterDiscovery->getMaster();
     $this->assertInstanceOf('\\PSRedis\\Client', $masterNode, 'When backing off is reset on each discovery, we should have received the master node here');
 }