Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Commit

Permalink
Add counter to prevent infinite loop. bunq#109
Browse files Browse the repository at this point in the history
  • Loading branch information
OGKevin committed Mar 16, 2019
1 parent 506ffdd commit a1c1ba1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 15 deletions.
39 changes: 30 additions & 9 deletions src/Http/Handler/ResponseHandlerRateLimit.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
<?php declare(strict_types=1);

<?php
declare(strict_types=1);

namespace bunq\Http\Handler;


use bunq\Http\ApiClient;
use phpDocumentor\Reflection\Types\This;
use bunq\Http\RequestRetryer;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
Expand All @@ -17,13 +14,18 @@
class ResponseHandlerRateLimit extends ResponseHandlerBase
{
/**
* @var RequestRetryert
* @var RequestRetryer
*/
private $retryer;

/**
* @var string[]
*/
private $retryMap;

/**
* ResponseHandlerRateLimit constructor.
* @param ApiClient $client
* @param RequestRetryer $retryer
*/
public function __construct(RequestRetryer $retryer)
{
Expand All @@ -39,10 +41,29 @@ public function __construct(RequestRetryer $retryer)
public function execute(ResponseInterface $response, RequestInterface $request): ResponseInterface
{
if ($response->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;
}
}

/**
* @param string $url
*/
private function incRetryCounter(string $url)
{
if (isset($this->retryMap[$url])) {
$this->retryMap[$url]++;
} else {
$this->retryMap[$url] = 1;
}
}
}
39 changes: 37 additions & 2 deletions tests/Http/RequestRertyerForTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);


namespace bunq\test\Http;
Expand All @@ -14,12 +15,46 @@
*/
class RequestRertyerForTest implements RequestRetryer
{
/**
* @var bool
*/
private $retry;

/**
* @var int
*/
private $calledCounter = 0;

/**
* RequestRertyerForTest constructor.
* @param bool $retry
*/
public function __construct(bool $retry = false)
{
$this->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();
}
}

/**
* @return int
*/
public function getCalledCounter(): int
{
return $this->calledCounter;
}
}
41 changes: 37 additions & 4 deletions tests/Http/ResponseHandlerRateLimitTest.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);

namespace bunq\test\Http;

use bunq\Http\Handler\ResponseHandlerRateLimit;
use bunq\test\BunqSdkTestBase;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
* Class ResponseHandlerRateLimitTest
Expand All @@ -14,14 +17,44 @@
class ResponseHandlerRateLimitTest extends BunqSdkTestBase
{
/**
* @return array
*/
public function testExecute()
public function dataProviderTestExecute(): array
{
$sut = new ResponseHandlerRateLimit(new RequestRertyerForTest());
return [
'retry once' => [
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());
}

/**
Expand Down

0 comments on commit a1c1ba1

Please sign in to comment.