diff --git a/src/AutoScaler.php b/src/AutoScaler.php index 7c3be16e..9946edbc 100644 --- a/src/AutoScaler.php +++ b/src/AutoScaler.php @@ -95,9 +95,15 @@ protected function numberOfWorkersPerQueue(Supervisor $supervisor, Collection $t $timeToClearAll = $timeToClear->sum(); return $timeToClear->mapWithKeys(function ($timeToClear, $queue) use ($supervisor, $timeToClearAll) { - return $timeToClearAll > 0 && $supervisor->options->autoScaling() - ? [$queue => (($timeToClear / $timeToClearAll) * $supervisor->options->maxProcesses)] - : [$queue => $supervisor->options->maxProcesses / count($supervisor->processPools)]; + if ($timeToClearAll > 0 && + $supervisor->options->autoScaling()) { + return [$queue => (($timeToClear / $timeToClearAll) * $supervisor->options->maxProcesses)]; + } elseif ($timeToClearAll == 0 && + $supervisor->options->autoScaling()) { + return [$queue => $supervisor->options->minProcesses]; + } + + return [$queue => $supervisor->options->maxProcesses / count($supervisor->processPools)]; })->sort(); } diff --git a/tests/Feature/AutoScalerTest.php b/tests/Feature/AutoScalerTest.php index af920660..a54af322 100644 --- a/tests/Feature/AutoScalerTest.php +++ b/tests/Feature/AutoScalerTest.php @@ -51,18 +51,66 @@ public function test_balance_stays_even_when_queue_is_empty() $scaler->scale($supervisor); + $this->assertEquals(4, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(4, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + + $this->assertEquals(3, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(3, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + + $this->assertEquals(2, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(2, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + + $this->assertEquals(1, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['second']->totalProcessCount()); + } + + public function test_balancer_assigns_more_processes_on_busy_queue() + { + [$scaler, $supervisor] = $this->with_scaling_scenario(10, [ + 'first' => ['current' => 1, 'size' => 50, 'runtime' => 50], + 'second' => ['current' => 1, 'size' => 0, 'runtime' => 0], + ]); + + $scaler->scale($supervisor); + $scaler->scale($supervisor); + + $this->assertEquals(3, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + $scaler->scale($supervisor); + $this->assertEquals(5, $supervisor->processPools['first']->totalProcessCount()); - $this->assertEquals(5, $supervisor->processPools['second']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + $scaler->scale($supervisor); + + $this->assertEquals(7, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['second']->totalProcessCount()); + + $scaler->scale($supervisor); + $scaler->scale($supervisor); + $scaler->scale($supervisor); + + $this->assertEquals(9, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['second']->totalProcessCount()); } - public function test_balancing_a_single_queue_assigns_it_the_max_workers() + public function test_balancing_a_single_queue_assigns_it_the_min_workers_with_empty_queue() { [$scaler, $supervisor] = $this->with_scaling_scenario(5, [ - 'first' => ['current' => 4, 'size' => 0, 'runtime' => 0], + 'first' => ['current' => 2, 'size' => 0, 'runtime' => 0], ]); $scaler->scale($supervisor); - $this->assertEquals(5, $supervisor->processPools['first']->totalProcessCount()); + $this->assertEquals(1, $supervisor->processPools['first']->totalProcessCount()); } public function test_scaler_will_not_scale_past_max_process_threshold_under_high_load()