Lines
90.32%
28 / 31
Methods
25.00%
1 / 4
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| decider | 93.33% | 14 / 15 | 0.00% | 0 / 1 | 5.01 | ||
| delay | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | ||
| delayMs | 100.00% | 6 / 6 | 100.00% | 1 / 1 | 3 | ||
| retryAfterMs | 88.88% | 8 / 9 | 0.00% | 0 / 1 | 4.02 | ||
| 18 | final class RetryPolicy | |
| 19 | { | |
| 20 | public static function decider(int $maxRetries): callable | |
| 21 | { | |
| 22 | return static function ( | |
| 23 | int $retries, | |
| 24 | RequestInterface $request, | |
| 25 | ?ResponseInterface $response = null, | |
| 26 | ?\Throwable $exception = null, | |
| 27 | ) use ($maxRetries): bool { | |
| 28 | if ($retries >= $maxRetries) { | |
| 29 | return false; | |
| 30 | } | |
| 31 | if ($exception instanceof ConnectException) { | |
| 32 | return true; | |
| 33 | } | |
| 34 | if (null !== $response) { | |
| 35 | $status = $response->getStatusCode(); | |
| 36 | ||
| 37 | return $status >= 500 || 429 === $status; | |
| 38 | } | |
| 39 | ||
| 40 | return false; | |
| 41 | }; | |
| 42 | } | |
| 43 | ||
| 44 | public static function delay(): callable | |
| 45 | { | |
| 46 | return self::delayMs(...); | |
| 47 | } | |
| 48 | ||
| 49 | public static function delayMs(int $retries, ?ResponseInterface $response = null): int | |
| 50 | { | |
| 51 | if (null !== $response) { | |
| 52 | $retryAfterMs = self::retryAfterMs($response); | |
| 53 | if (null !== $retryAfterMs) { | |
| 54 | return $retryAfterMs; | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | $base = 100 * 2 ** ($retries - 1); | |
| 59 | ||
| 60 | return (int) ($base + random_int(0, (int) $base)); | |
| 61 | } | |
| 62 | ||
| 63 | private static function retryAfterMs(ResponseInterface $response): ?int | |
| 64 | { | |
| 65 | $retryAfter = $response->getHeaderLine('Retry-After'); | |
| 66 | if ('' === $retryAfter) { | |
| 67 | return null; | |
| 68 | } | |
| 69 | ||
| 70 | if (is_numeric($retryAfter)) { | |
| 71 | return max((int) ((float) $retryAfter * 1000), 0); | |
| 72 | } | |
| 73 | ||
| 74 | $when = strtotime($retryAfter); | |
| 75 | if (false === $when) { | |
| 76 | return null; | |
| 77 | } | |
| 78 | ||
| 79 | return max(($when - time()) * 1000, 0); | |
| 80 | } | |
| 81 | } |