/** * {@inheritdoc} */ public function add(NodeConnectionInterface $connection) { $parameters = $connection->getParameters(); if (isset($parameters->alias)) { $this->pool[$parameters->alias] = $connection; } else { $this->pool[] = $connection; } $weight = isset($parameters->weight) ? $parameters->weight : null; $this->distributor->add($connection, $weight); }
/** * {@inheritdoc} */ public function remove(NodeConnectionInterface $connection) { if ($connection->getParameters()->alias === 'master') { $this->master = null; $this->reset(); return true; } else { if (($id = array_search($connection, $this->slaves, true)) !== false) { unset($this->slaves[$id]); $this->reset(); return true; } } return false; }
/** * {@inheritdoc} */ public function add(NodeConnectionInterface $connection) { $parameters = $connection->getParameters(); $this->pool[(string) $connection] = $connection; if (isset($parameters->alias)) { $this->aliases[$parameters->alias] = $connection; } $this->distributor->add($connection, $parameters->weight); }
/** * {@inheritdoc} */ public function disconnect() { if ($this->master) { $this->master->disconnect(); } foreach ($this->slaves as $connection) { $connection->disconnect(); } }
/** * {@inheritdoc} */ public function connect() { if (!$this->current) { if (!($this->current = $this->pickSlave())) { $this->current = $this->getMaster(); } } $this->current->connect(); }
/** * {@inheritdoc} */ public function executeCommand(CommandInterface $command) { if (null === $this->logger) { return $this->connection->executeCommand($command); } $startTime = microtime(true); $result = $this->connection->executeCommand($command); $duration = (microtime(true) - $startTime) * 1000; $error = $result instanceof Error ? (string) $result : false; $this->logger->logCommand($this->commandToString($command), $duration, $this->getParameters()->alias, $error); return $result; }
/** * {@inheritdoc} */ protected function executeSingleNode(NodeConnectionInterface $connection, SplQueue $commands) { $responses = array(); $sizeOfPipe = count($commands); foreach ($commands as $command) { try { $connection->writeRequest($command); } catch (CommunicationException $exception) { return array_fill(0, $sizeOfPipe, $exception); } } for ($i = 0; $i < $sizeOfPipe; $i++) { $command = $commands->dequeue(); try { $responses[$i] = $connection->readResponse($command); } catch (CommunicationException $exception) { $add = count($commands) - count($responses); $responses = array_merge($responses, array_fill(0, $add, $exception)); break; } } return $responses; }
/** * Prepares a connection instance after its initialization. * * @param NodeConnectionInterface $connection Connection instance. */ protected function prepareConnection(NodeConnectionInterface $connection) { $parameters = $connection->getParameters(); if (isset($parameters->password)) { $connection->addConnectCommand(new RawCommand(array('AUTH', $parameters->password))); } if (isset($parameters->database)) { $connection->addConnectCommand(new RawCommand(array('SELECT', $parameters->database))); } }
/** * Queries the specified node of the cluster to fetch the updated slots map. * * When the connection fails, this method tries to execute the same command * on a different connection picked at random from the pool of known nodes, * up until the retry limit is reached. * * @param NodeConnectionInterface $connection Connection to a node of the cluster. * * @return mixed */ private function queryClusterNodeForSlotMap(NodeConnectionInterface $connection) { $retries = 0; $command = RawCommand::create('CLUSTER', 'SLOTS'); RETRY_COMMAND: try { $response = $connection->executeCommand($command); } catch (ConnectionException $exception) { $connection = $exception->getConnection(); $connection->disconnect(); $this->remove($connection); if ($retries === $this->retryLimit) { throw $exception; } if (!($connection = $this->getRandomConnection())) { throw new ClientException('No connections left in the pool for `CLUSTER SLOTS`'); } ++$retries; goto RETRY_COMMAND; } return $response; }
/** * Asserts that the connection is not using a persistent resource stream. * * This assertion will trigger a connect() operation if the connection has * not been open yet. * * @param NodeConnectionInterface $connection Connection instance. */ protected function assertNonPersistentConnection(NodeConnectionInterface $connection) { $this->assertSame('stream', get_resource_type($connection->getResource())); }
/** * Discovers the replication configuration by contacting one of the slaves. * * @param NodeConnectionInterface $connection Connection to one of the slaves. * @param FactoryInterface $connectionFactory Connection factory instance. */ protected function discoverFromSlave(NodeConnectionInterface $connection, FactoryInterface $connectionFactory) { $response = $connection->executeCommand(RawCommand::create('INFO', 'REPLICATION')); $replication = $this->handleInfoResponse($response); if ($replication['role'] !== 'slave') { throw new ClientException("Role mismatch (expected slave, got master) [{$connection}]"); } $masterConnection = $connectionFactory->create(array('host' => $replication['master_host'], 'port' => $replication['master_port'], 'role' => 'master')); $this->add($masterConnection); $this->discoverFromMaster($masterConnection, $connectionFactory); }