Skip to content

Commit

Permalink
Update strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
denisyukphp committed Jun 26, 2024
1 parent 5068168 commit 1bf9c11
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/Cluster/ClusterPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function pick(CollectionInterface $collection, array $context = []): Node
}

if (!\is_string($context['cluster'])) {
throw new \RuntimeException('The parameter "cluster" must be as a string.'); // @codeCoverageIgnore
throw new \RuntimeException(sprintf('The parameter "cluster" must be as a string, %s given.', get_debug_type($context['cluster']))); // @codeCoverageIgnore
}

if (!isset($this->clusterNames[$context['cluster']])) {
Expand Down
2 changes: 1 addition & 1 deletion src/RoundRobinThrottler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function pick(CollectionInterface $collection, array $context = []): Node
}

if (isset($context['counter']) && !\is_string($context['counter'])) {
throw new \RuntimeException(sprintf('The parameter "counter" must be as string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
throw new \RuntimeException(sprintf('The parameter "counter" must be as a string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
}

$counter = $context['counter'] ?? spl_object_hash($collection);
Expand Down
2 changes: 1 addition & 1 deletion src/SmoothWeightedRoundRobinThrottler.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function pick(CollectionInterface $collection, array $context = []): Node
}

if (isset($context['counter']) && !\is_string($context['counter'])) {
throw new \RuntimeException(sprintf('The parameter "counter" must be as string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
throw new \RuntimeException(sprintf('The parameter "counter" must be as a string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
}

$counter = $context['counter'] ?? spl_object_hash($collection);
Expand Down
2 changes: 1 addition & 1 deletion src/WeightedRandomThrottler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function pick(CollectionInterface $collection, array $context = []): Node
$randomWeight = mt_rand(1, $sumWeight);

foreach ($collection as $node) {
if (0 == $node->getWeight()) {
if (0 === $node->getWeight()) {
throw new \RuntimeException('All nodes in the collection must be weighted.'); // @codeCoverageIgnore
}

Expand Down
45 changes: 31 additions & 14 deletions src/WeightedRoundRobinThrottler.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,18 @@

final class WeightedRoundRobinThrottler implements ThrottlerInterface
{
private int $gcdWeight = 0;
private int $maxWeight = 0;
private int $currentWeight = 0;
/**
* @var array<string, int>
*/
private array $gcdWeight = [];
/**
* @var array<string, int>
*/
private array $maxWeight = [];
/**
* @var array<string, int>
*/
private array $currentWeight = [];

public function __construct(
private CounterInterface $counter,
Expand All @@ -29,34 +38,42 @@ public function pick(CollectionInterface $collection, array $context = []): Node
}

if (isset($context['counter']) && !\is_string($context['counter'])) {
throw new \RuntimeException(sprintf('The parameter "counter" must be as string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
throw new \RuntimeException(sprintf('The parameter "counter" must be as a string, %s given.', get_debug_type($context['counter']))); // @codeCoverageIgnore
}

$counter = $context['counter'] ?? spl_object_hash($collection);

foreach ($collection as $node) {
if (0 == $node->getWeight()) {
throw new \RuntimeException('All nodes in the collection must be weighted.'); // @codeCoverageIgnore
}
if (!isset($this->gcdWeight[$counter]) || !isset($this->maxWeight[$counter]) || !isset($this->currentWeight[$counter])) {
$this->gcdWeight[$counter] = 0;
$this->maxWeight[$counter] = 0;
$this->currentWeight[$counter] = 0;
}

$this->gcdWeight = gcd($this->gcdWeight, $node->getWeight());
$this->maxWeight = max($this->maxWeight, $node->getWeight());
if (0 === $this->gcdWeight[$counter] || 0 === $this->maxWeight[$counter] || 0 === $this->currentWeight[$counter]) {
foreach ($collection as $node) {
if (0 === $node->getWeight()) {
throw new \RuntimeException('All nodes in the collection must be weighted.'); // @codeCoverageIgnore
}

$this->gcdWeight[$counter] = gcd($this->gcdWeight[$counter], $node->getWeight());
$this->maxWeight[$counter] = max($this->maxWeight[$counter], $node->getWeight());
}
}

while (true) {
$key = $this->counter->next($counter) % \count($collection);

if (0 == $key) {
$this->currentWeight -= $this->gcdWeight;
$this->currentWeight[$counter] -= $this->gcdWeight[$counter];

if (0 >= $this->currentWeight) {
$this->currentWeight = $this->maxWeight;
if (0 >= $this->currentWeight[$counter]) {
$this->currentWeight[$counter] = $this->maxWeight[$counter];
}
}

$node = $collection->get($key);

if ($node->getWeight() >= $this->currentWeight) {
if ($node->getWeight() >= $this->currentWeight[$counter]) {
return $node;
}
}
Expand Down

0 comments on commit 1bf9c11

Please sign in to comment.