Skip to content

Commit f2ad9d9

Browse files
committed
Add support for the Retry-After header
1 parent 1f3ce8e commit f2ad9d9

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ An API client for Envato in PHP, with simplified OAuth, token storage, and reque
1212
- [Persistent OAuth](#persistent-oauth)
1313
- [Sending Requests](#sending-requests)
1414
- [Getting Request Time](#getting-request-time)
15+
- [Rate Limiting](#rate-limiting)
1516
- [Catalog](#catalog)
1617
- [Look up a public collection](#look-up-a-public-collection)
1718
- [Look up a single item](#look-up-a-single-item)
@@ -178,6 +179,28 @@ $response = $client->profile->portfolio([
178179
To determine how long a request took to execute (in seconds), you can reference the `$response->time` property.
179180

180181

182+
### Rate Limiting
183+
184+
If you're being rate limited, the client will throw a `TooManyRequestsException` exception. The exception instance has
185+
methods to help work with the rate limit.
186+
187+
```php
188+
use Herbert\Envato\Exceptions\TooManyRequestsException;
189+
190+
try {
191+
$item = $client->catalog->item(['id' => 1234567]);
192+
}
193+
catch (TooManyRequestsException $e) {
194+
// Get the number of seconds remaining (float)
195+
$secondsRemaining = $e->getSecondsRemaining();
196+
197+
//
198+
$timestamp = $e->getRetryTime();
199+
$e->wait();
200+
}
201+
```
202+
203+
181204
## Catalog
182205

183206
### Look up a public collection

src/Envato/Endpoint.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ private function perform(&$uri, array &$variables) {
109109

110110
// 429 Too Many Requests
111111
elseif ($response->getStatusCode() == 429) {
112-
throw new TooManyRequestsException();
112+
throw new TooManyRequestsException(
113+
$response->hasHeader('Retry-After') ?
114+
intval($response->getHeader('Retry-After')[0]) : 0
115+
);
113116
}
114117

115118
// Generate response object
@@ -152,4 +155,4 @@ private function createHttpClient() {
152155
}
153156
}
154157

155-
}
158+
}

src/Envato/Exceptions/TooManyRequestsException.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,40 @@
33
namespace Herbert\Envato\Exceptions {
44
class TooManyRequestsException extends EnvatoException
55
{
6+
private $epoch;
7+
8+
public function __construct($seconds) {
9+
$this->epoch = microtime(true) + $seconds;
10+
}
11+
12+
/**
13+
* Returns the number of seconds remaining until the next available request.
14+
* @return float
15+
*/
16+
public function getSecondsRemaining() {
17+
return max(0, $this->epoch - microtime(true));
18+
}
19+
20+
/**
21+
* Returns an epoch (unix) timestamp containing the time when the request can be retried. Note that this
22+
* timestamp is in seconds, but contains microseconds.
23+
*
24+
* @return float
25+
*/
26+
public function getRetryTime() {
27+
return $this->epoch;
28+
}
29+
30+
/**
31+
* Sleeps the script until the `Retry-After` time.
32+
*/
33+
public function wait() {
34+
$seconds = ceil($this->getSecondsRemaining());
35+
36+
if ($seconds > 0) {
37+
sleep($seconds);
38+
}
39+
}
640
}
741
}
842

src/Envato/ResultSet.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ public function __get($property) {
2828
}
2929
}
3030

31-
}
31+
}

0 commit comments

Comments
 (0)