|
6 | 6 |
|
7 | 7 | namespace AaronFrancis\Flaky; |
8 | 8 |
|
| 9 | +use Illuminate\Contracts\Cache\Repository; |
9 | 10 | use Illuminate\Support\Arr; |
10 | 11 | use Illuminate\Support\Facades\Cache; |
11 | 12 | use Illuminate\Support\Traits\Macroable; |
| 13 | +use Throwable; |
12 | 14 |
|
13 | 15 | class Arbiter |
14 | 16 | { |
15 | 17 | use Macroable; |
16 | 18 |
|
17 | | - public $failuresAllowedForSeconds = 60 * 60 * 24 * 365 * 10; |
| 19 | + public int $failuresAllowedForSeconds = 60 * 60 * 24 * 365 * 10; |
18 | 20 |
|
19 | | - public $consecutiveFailuresAllowed = INF; |
| 21 | + public int|float $consecutiveFailuresAllowed = INF; |
20 | 22 |
|
21 | | - public $totalFailuresAllowed = INF; |
| 23 | + public int|float $totalFailuresAllowed = INF; |
22 | 24 |
|
| 25 | + /** @var callable(Throwable): void */ |
23 | 26 | public $handleFailuresWith; |
24 | 27 |
|
25 | | - protected $key; |
| 28 | + protected string $key; |
26 | 29 |
|
27 | | - protected $totalFailures; |
| 30 | + protected int $totalFailures; |
28 | 31 |
|
29 | | - protected $consecutiveFailures; |
| 32 | + protected int $consecutiveFailures; |
30 | 33 |
|
31 | | - protected $deadline; |
| 34 | + protected ?int $deadline; |
32 | 35 |
|
33 | | - protected $cache; |
| 36 | + protected Repository $cache; |
34 | 37 |
|
35 | | - public function __construct($id) |
| 38 | + public function __construct(string $id) |
36 | 39 | { |
37 | 40 | $this->key = "flaky::$id"; |
38 | 41 | $this->cache = Cache::store(); |
39 | 42 |
|
| 43 | + /** @var array{total?: int, consecutive?: int, deadline?: int|null} $stats */ |
40 | 44 | $stats = $this->cache->get($this->key, []); |
41 | 45 |
|
42 | 46 | $this->totalFailures = Arr::get($stats, 'total', 0); |
43 | 47 | $this->consecutiveFailures = Arr::get($stats, 'consecutive', 0); |
44 | 48 | $this->deadline = Arr::get($stats, 'deadline'); |
45 | 49 |
|
46 | | - $this->handleFailuresWith = function ($e) { |
| 50 | + $this->handleFailuresWith = function (Throwable $e): never { |
47 | 51 | throw $e; |
48 | 52 | }; |
49 | 53 | } |
50 | 54 |
|
51 | | - public function handle($exception) |
| 55 | + public function handle(?Throwable $exception): void |
52 | 56 | { |
53 | 57 | $this->deadline = $this->deadline ?? $this->freshDeadline(); |
54 | 58 |
|
55 | | - if ($exception) { |
| 59 | + if ($exception !== null) { |
56 | 60 | $this->totalFailures++; |
57 | 61 | $this->consecutiveFailures++; |
58 | 62 | } |
59 | 63 |
|
60 | 64 | $this->updateCachedStats($exception); |
61 | 65 |
|
62 | | - if (!is_null($exception) && $this->outOfBounds()) { |
| 66 | + if ($exception !== null && $this->outOfBounds()) { |
63 | 67 | $this->callHandler($exception); |
64 | 68 | } |
65 | 69 | } |
66 | 70 |
|
67 | | - public function handleFailures($callback) |
| 71 | + public function handleFailures(callable $callback): void |
68 | 72 | { |
69 | 73 | $this->handleFailuresWith = $callback; |
70 | 74 | } |
71 | 75 |
|
72 | | - public function outOfBounds() |
| 76 | + public function outOfBounds(): bool |
73 | 77 | { |
74 | 78 | return $this->tooManyConsecutiveFailures() || $this->tooManyTotalFailures() || $this->beyondDeadline(); |
75 | 79 | } |
76 | 80 |
|
77 | | - public function tooManyConsecutiveFailures() |
| 81 | + public function tooManyConsecutiveFailures(): bool |
78 | 82 | { |
79 | 83 | return $this->consecutiveFailures > $this->consecutiveFailuresAllowed; |
80 | 84 | } |
81 | 85 |
|
82 | | - public function tooManyTotalFailures() |
| 86 | + public function tooManyTotalFailures(): bool |
83 | 87 | { |
84 | 88 | return $this->totalFailures > $this->totalFailuresAllowed; |
85 | 89 | } |
86 | 90 |
|
87 | | - public function beyondDeadline() |
| 91 | + public function beyondDeadline(): bool |
88 | 92 | { |
89 | 93 | return now()->timestamp > $this->deadline; |
90 | 94 | } |
91 | 95 |
|
92 | | - protected function callHandler($exception) |
| 96 | + protected function callHandler(Throwable $exception): void |
93 | 97 | { |
94 | 98 | call_user_func($this->handleFailuresWith, $exception); |
95 | 99 | } |
96 | 100 |
|
97 | | - protected function freshDeadline() |
| 101 | + protected function freshDeadline(): int |
98 | 102 | { |
99 | 103 | return now()->addSeconds($this->failuresAllowedForSeconds)->timestamp; |
100 | 104 | } |
101 | 105 |
|
102 | | - protected function updateCachedStats($exception) |
| 106 | + protected function updateCachedStats(?Throwable $exception): void |
103 | 107 | { |
104 | | - $failed = !is_null($exception); |
| 108 | + $failed = $exception !== null; |
105 | 109 |
|
106 | 110 | $stats = $failed ? [ |
107 | 111 | // Reset if we passed, otherwise just store the incremented value. |
|
0 commit comments