Lines
100.00%
14 / 14
Methods
100.00%
5 / 5
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| countUsedAttempts | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| claimAttempt | 100.00% | 7 / 7 | 100.00% | 1 / 1 | 2 | ||
| forgetAttempts | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| listAttemptsWithinWindow | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 1 | ||
| 11 | final class RestartBudget | |
| 12 | { | |
| 13 | /** @var array<int, list<MonotonicTime>> */ | |
| 14 | private array $restarts = []; | |
| 15 | ||
| 16 | public function __construct( | |
| 17 | private readonly SupervisionConfig $supervision, | |
| 18 | ) {} | |
| 19 | ||
| 20 | public function countUsedAttempts(WorkerId $workerId, MonotonicTime $now): int | |
| 21 | { | |
| 22 | return \count($this->listAttemptsWithinWindow($workerId, $now)); | |
| 23 | } | |
| 24 | ||
| 25 | public function claimAttempt(WorkerId $workerId, MonotonicTime $now): ?int | |
| 26 | { | |
| 27 | $spent = $this->listAttemptsWithinWindow($workerId, $now); | |
| 28 | ||
| 29 | if (\count($spent) >= $this->supervision->restartAttempts) { | |
| 30 | $this->restarts[$workerId->value] = $spent; | |
| 31 | ||
| 32 | return null; | |
| 33 | } | |
| 34 | ||
| 35 | $spent[] = $now; | |
| 36 | $this->restarts[$workerId->value] = $spent; | |
| 37 | ||
| 38 | return \count($spent); | |
| 39 | } | |
| 40 | ||
| 41 | public function forgetAttempts(WorkerId $workerId): void | |
| 42 | { | |
| 43 | unset($this->restarts[$workerId->value]); | |
| 44 | } | |
| 45 | ||
| 46 | /** @return list<MonotonicTime> */ | |
| 47 | private function listAttemptsWithinWindow(WorkerId $workerId, MonotonicTime $now): array | |
| 48 | { | |
| 49 | return array_values(array_filter( | |
| 50 | $this->restarts[$workerId->value] ?? [], | |
| 51 | fn(MonotonicTime $at): bool => $this->supervision->restartWindow->isLongerThan($now->elapsedSince($at)), | |
| 52 | )); | |
| 53 | } | |
| 54 | } |