Skip to content

Commit 89bace5

Browse files
authored
Merge pull request #95 from tharropoulos/shuffle-nodes
refactor(api_call): improve node selection with shuffling
2 parents 23b84a8 + b875a4f commit 89bace5

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

src/ApiCall.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ private function makeRequest(string $method, string $endPoint, bool $asJson, arr
198198
$lastException = null;
199199
while ($numRetries < $this->config->getNumRetries() + 1) {
200200
$numRetries++;
201-
$node = $this->getNode();
201+
$node = $this->getNode($numRetries);
202202

203203
try {
204204
$url = $node->url() . $endPoint;
@@ -328,30 +328,54 @@ public function setNodeHealthCheck(Node $node, bool $isHealthy): void
328328
* Returns a healthy host from the pool in a round-robin fashion
329329
* Might return an unhealthy host periodically to check for recovery.
330330
*
331+
* @param int $requestNumber
331332
* @return Node
332333
*/
333-
public function getNode(): Lib\Node
334+
public function getNode(int $requestNumber = 0): Lib\Node
334335
{
336+
$this->logger->debug("Request #{$requestNumber}: Getting next node");
337+
335338
if ($this->nearestNode !== null) {
339+
$this->logger->debug(
340+
"Request #{$requestNumber}: Nodes Health: Nearest node is " .
341+
($this->nearestNode->isHealthy() ? "Healthy" : "Unhealthy")
342+
);
343+
336344
if ($this->nearestNode->isHealthy() || $this->nodeDueForHealthCheck($this->nearestNode)) {
345+
$this->logger->debug(
346+
"Request #{$requestNumber}: Using nearest node"
347+
);
337348
return $this->nearestNode;
338349
}
350+
$this->logger->debug("Request #{$requestNumber}: Falling back to individual nodes");
339351
}
340-
$i = 0;
341-
while ($i < count($this->nodes)) {
342-
$i++;
343-
$node = $this->nodes[$this->nodeIndex];
352+
353+
$candidateNode = $this->nodes[0];
354+
for ($i = 0; $i <= count($this->nodes); $i++) {
344355
$this->nodeIndex = ($this->nodeIndex + 1) % count($this->nodes);
345-
if ($node->isHealthy() || $this->nodeDueForHealthCheck($node)) {
346-
return $node;
356+
$candidateNode = $this->nodes[$this->nodeIndex];
357+
358+
$this->logger->debug(
359+
"Request #{$requestNumber}: Nodes Health: Node is " .
360+
($candidateNode->isHealthy() ? "Healthy" : "Unhealthy")
361+
);
362+
363+
if ($candidateNode->isHealthy() || $this->nodeDueForHealthCheck($candidateNode)) {
364+
$this->logger->debug(
365+
"Request #{$requestNumber}: Updated current node"
366+
);
367+
return $candidateNode;
347368
}
348369
}
349370

350371
/**
351372
* None of the nodes are marked healthy, but some of them could have become healthy since last health check.
352373
* So we will just return the next node.
353374
*/
354-
return $this->nodes[$this->nodeIndex];
375+
$this->logger->debug(
376+
"Request #{$requestNumber}: No healthy nodes were found. Returning the next node"
377+
);
378+
return $candidateNode;
355379
}
356380

357381
/**

src/Lib/Configuration.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class Configuration
6666
*/
6767
private int $logLevel;
6868

69+
/**
70+
* @var bool
71+
*/
72+
private bool $randomizeNodes;
73+
6974
/**
7075
* Configuration constructor.
7176
*
@@ -83,6 +88,11 @@ public function __construct(array $config)
8388
$this->nodes[] = new Node($node['host'], $node['port'], $node['path'] ?? '', $node['protocol']);
8489
}
8590

91+
$this->randomizeNodes = $config['randomize_nodes'] ?? true;
92+
if ($this->randomizeNodes) {
93+
shuffle($this->nodes);
94+
}
95+
8696
$nearestNode = $config['nearest_node'] ?? null;
8797
$this->nearestNode = null;
8898
if (null !== $nearestNode) {

0 commit comments

Comments
 (0)