diff --git a/src/Http/Handler/ResponseHandlerRateLimit.php b/src/Http/Handler/ResponseHandlerRateLimit.php index 2c31ab10..59797425 100644 --- a/src/Http/Handler/ResponseHandlerRateLimit.php +++ b/src/Http/Handler/ResponseHandlerRateLimit.php @@ -1,11 +1,8 @@ -getStatusCode() === 429) { - usleep(1500); + $this->incRetryCounter($request->getUri()->__toString()); + if ($this->retryMap[$request->getUri()->__toString()] > 2) { + // let the error handler further down the stack handle the 429 error + return $response; + } + usleep(1100 * $this->retryMap[$request->getUri()->__toString()]); return $this->retryer->retryRequest($request); } + $this->retryMap[$request->getUri()->__toString()] = 0; + return $response; } -} \ No newline at end of file + + /** + * @param string $url + */ + private function incRetryCounter(string $url) + { + if (isset($this->retryMap[$url])) { + $this->retryMap[$url]++; + } else { + $this->retryMap[$url] = 1; + } + } +} diff --git a/tests/Http/RequestRertyerForTest.php b/tests/Http/RequestRertyerForTest.php index c92d3346..57d08ff9 100644 --- a/tests/Http/RequestRertyerForTest.php +++ b/tests/Http/RequestRertyerForTest.php @@ -1,4 +1,5 @@ -retry = $retry; + } + /** * @param RequestInterface $request * @return ResponseInterface */ public function retryRequest(RequestInterface $request): ResponseInterface { + $this->calledCounter++; + + if ($this->retry) { + $this->retry = false; + return $this->retryRequest($request); + } + return new Response(); } -} \ No newline at end of file + + /** + * @return int + */ + public function getCalledCounter(): int + { + return $this->calledCounter; + } +} diff --git a/tests/Http/ResponseHandlerRateLimitTest.php b/tests/Http/ResponseHandlerRateLimitTest.php index a7a5c4b5..809984bf 100644 --- a/tests/Http/ResponseHandlerRateLimitTest.php +++ b/tests/Http/ResponseHandlerRateLimitTest.php @@ -1,4 +1,5 @@ - [ + new Response(429), + new Request('$method', '$uri'), + false, + 1 + ], + 'retry twice' => [ + new Response(429), + new Request('$method', '$uri'), + true, + 2, + ], + 'dont retry' => [ + new Response(200), + new Request('$method', '$uri'), + true, + 0, + ], + ]; + } + + /** + * @dataProvider dataProviderTestExecute + */ + public function testExecute(ResponseInterface $response, RequestInterface $request, bool $retry, int $retryCounter) + { + $retryer = new RequestRertyerForTest($retry); + $sut = new ResponseHandlerRateLimit($retryer); - $response = $sut->execute(new Response(429), new Request('GET', 'https://whatthecommit.com/index.txt')); + $response = $sut->execute($response, $request); static::assertEquals(200, $response->getStatusCode()); + static::assertEquals($retryCounter, $retryer->getCalledCounter()); } /**