Lines
100.00%
16 / 16
Methods
100.00%
3 / 3
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| planWorkerSlots | 100.00% | 11 / 11 | 100.00% | 1 / 1 | 3 | ||
| resolvePoolSize | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 2 | ||
| 13 | final readonly class AppPlacement | |
| 14 | { | |
| 15 | public function __construct(private int $autoPoolSize) {} | |
| 16 | ||
| 17 | public function planWorkerSlots(AppDefinitionCollection $apps, StewartConfig $config): WorkerSlotCollection | |
| 18 | { | |
| 19 | $poolSize = $this->resolvePoolSize($apps, $config->workers); | |
| 20 | $byWorker = []; | |
| 21 | $next = 0; | |
| 22 | ||
| 23 | foreach ($apps as $app) { | |
| 24 | $workerId = $app->worker ?? $next++ % $poolSize; | |
| 25 | $byWorker[$workerId][] = $app; | |
| 26 | } | |
| 27 | ||
| 28 | ksort($byWorker); | |
| 29 | $slots = []; | |
| 30 | ||
| 31 | foreach ($byWorker as $workerId => $pinned) { | |
| 32 | $slots[] = new WorkerSlot(WorkerId::fromInt($workerId), AppDefinitionCollection::keyedByAppId($pinned)); | |
| 33 | } | |
| 34 | ||
| 35 | return WorkerSlotCollection::fromList($slots); | |
| 36 | } | |
| 37 | ||
| 38 | private function resolvePoolSize(AppDefinitionCollection $apps, int $workers): int | |
| 39 | { | |
| 40 | if ($workers > 0) { | |
| 41 | return $workers; | |
| 42 | } | |
| 43 | ||
| 44 | $highestPin = max([-1, ...$apps->mapToList(static fn(AppDefinition $app): int => $app->worker ?? -1)]); | |
| 45 | ||
| 46 | return max(1, $this->autoPoolSize, $highestPin + 1); | |
| 47 | } | |
| 48 | } |