From 7950745b37453ba11a6a92dc801fe36ee958fcb3 Mon Sep 17 00:00:00 2001 From: Budi Chandra Date: Tue, 29 Aug 2017 09:54:58 -0700 Subject: [PATCH 1/3] Automatically retry when rate limit is reached --- lib/Client.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/Client.php b/lib/Client.php index bd2d67b..3d446a6 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -134,10 +134,11 @@ private function buildUrl($queryParams = null) * @param string $url the final url to call * @param array $body request body * @param array $headers any additional request headers + * @param bool $retryOnLimit should retry if rate limit is reach? * * @return Response object */ - public function makeRequest($method, $url, $body = null, $headers = null) + public function makeRequest($method, $url, $body = null, $headers = null, $retryOnLimit = true) { $curl = curl_init($url); @@ -169,8 +170,17 @@ public function makeRequest($method, $url, $body = null, $headers = null) $responseHeaders = array_map('trim', $responseHeaders); curl_close($curl); + + $response = new Response($statusCode, $responseBody, $responseHeaders); + + if ($statusCode == 429 && $retryOnLimit) { + $headers = $response->headers(true); + $sleepDurations = $headers['X-Ratelimit-Reset'] - time(); + sleep($sleepDurations > 0 ? $sleepDurations : 0); + return $this->makeRequest($method, $url, $body, $headers, false); + } - return new Response($statusCode, $responseBody, $responseHeaders); + return $response; } /** From 596fe0dc6964d71e34a9e79e725942c148faff4f Mon Sep 17 00:00:00 2001 From: Budi Chandra Date: Wed, 30 Aug 2017 18:27:46 -0700 Subject: [PATCH 2/3] Add default flag, Make default to false --- examples/example.php | 9 +++++++++ lib/Client.php | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/examples/example.php b/examples/example.php index ce86d73..4ec9c73 100644 --- a/examples/example.php +++ b/examples/example.php @@ -18,6 +18,15 @@ echo $response->body(); echo $response->headers(); +// GET with auto retry on rate limit +$query_params = ['limit' => 100, 'offset' => 0]; +$request_headers = ['X-Mock: 200']; +$retryOnLimit = true; +$response = $client->api_keys()->get(null, $query_params, $request_headers, $retryOnLimit); +echo $response->statusCode(); +echo $response->body(); +echo $response->headers(); + // POST $request_body = [ 'name' => 'My PHP API Key', diff --git a/lib/Client.php b/lib/Client.php index 3d446a6..d3ca94d 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -32,17 +32,20 @@ class Client protected $curlOptions; /** @var array */ private $methods; + /** @var bool */ + private $retryOnLimit; /** * Initialize the client * - * @param string $host the base url (e.g. https://api.sendgrid.com) - * @param array $headers global request headers - * @param string $version api version (configurable) - * @param array $path holds the segments of the url path - * @param array $curlOptions extra options to set during curl initialization + * @param string $host the base url (e.g. https://api.sendgrid.com) + * @param array $headers global request headers + * @param string $version api version (configurable) + * @param array $path holds the segments of the url path + * @param array $curlOptions extra options to set during curl initialization + * @param bool $retryOnLimit set default retry on limit flag */ - public function __construct($host, $headers = null, $version = null, $path = null, $curlOptions = null) + public function __construct($host, $headers = null, $version = null, $path = null, $curlOptions = null, $retryOnLimit = false) { $this->host = $host; $this->headers = $headers ?: []; @@ -51,6 +54,8 @@ public function __construct($host, $headers = null, $version = null, $path = nul $this->curlOptions = $curlOptions ?: []; // These are the supported HTTP verbs $this->methods = ['delete', 'get', 'patch', 'post', 'put']; + + $this->retryOnLimit = $retryOnLimit; } /** @@ -138,7 +143,7 @@ private function buildUrl($queryParams = null) * * @return Response object */ - public function makeRequest($method, $url, $body = null, $headers = null, $retryOnLimit = true) + public function makeRequest($method, $url, $body = null, $headers = null, $retryOnLimit = false) { $curl = curl_init($url); @@ -221,7 +226,8 @@ public function __call($name, $args) $queryParams = isset($args[1]) ? $args[1] : null; $url = $this->buildUrl($queryParams); $headers = isset($args[2]) ? $args[2] : null; - return $this->makeRequest($name, $url, $body, $headers); + $retryOnLimit = isset($args[3]) ? $args[3] : $this->retryOnLimit; + return $this->makeRequest($name, $url, $body, $headers, $retryOnLimit); } return $this->_($name); From 50983ad87c63bae456afc87847e15c5de1f83a28 Mon Sep 17 00:00:00 2001 From: Budi Chandra Date: Thu, 31 Aug 2017 23:33:25 -0700 Subject: [PATCH 3/3] Fix unit test --- test/unit/MockClient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/MockClient.php b/test/unit/MockClient.php index 0254e5e..ae7ed79 100644 --- a/test/unit/MockClient.php +++ b/test/unit/MockClient.php @@ -10,11 +10,11 @@ class MockClient extends Client protected $requestHeaders; protected $url; - public function makeRequest($method, $url, $requestBody = null, $requestHeaders = null) + public function makeRequest($method, $url, $requestBody = null, $requestHeaders = null, $retryOnLimit = false) { $this->requestBody = $requestBody; $this->requestHeaders = $requestHeaders; $this->url = $url; return $this; } -} \ No newline at end of file +}