Skip to content

Commit

Permalink
Bug fix for Issue #28 & enhancement for #24 (#32)
Browse files Browse the repository at this point in the history
* Adding reservoir limitations

* Fix reservoir strategy bug & add custom timeout

Co-authored-by: James Li <[email protected]>
  • Loading branch information
jamesliupenn and James Li authored Jan 29, 2021
1 parent 640610c commit 9e871f5
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 9 deletions.
5 changes: 5 additions & 0 deletions README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ Pour commencer à utiliser l'API Onfleet, il vous suffit de créer un objet Onfl
```js
const onfleet = new Onfleet('<clé_api>');
```
En tant que champ facultatif, vous pouvez introduire un délai d'expiration personnalisé inférieur à la valeur par défaut de 70000 ms (délai d'expiration de l'API Onfleet par défaut) en fournissant un 2ème paramètre:
```js
const onfleet = new Onfleet('<clé_api>', 30000) // Cela mettra vos wrappers à expiration à 30000ms au lieu de 70000ms
```

### Authentification
Une fois que l'objet Onfleet est créé, vous pouvez utiliser une fonction utilitaire pour tester le noeud final d'authentification. Cette fonction renvoie un booléen:
```js
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ To start utilizing the Onfleet API, you simply need to create an Onfleet object
```js
const onfleet = new Onfleet('<api_key>');
```

As an optional field, you can introduce a customized timeout that is less than the default 70000ms (default Onfleet API timeout) by providing a 2nd parameter:
```js
const onfleet = new Onfleet('<api_key>', 30000) // This will set your wrappers to timeout at 30000ms instead of 70000ms
```

### Authentication
Once the Onfleet object is created, you can use a utility function to test on the authentication endpoint, this function returns a boolean:
```js
Expand Down
6 changes: 6 additions & 0 deletions README.zh-tw.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ npm install @types/onfleet__node-onfleet
```js
const onfleet = new Onfleet('<api_key>');
```

由於某些應用的執行逾時參數較低(例如Heroku的三十秒設定),您可以在創立物件時,提供一個低於70000ms、客製化的逾時參數:
```js
const onfleet = new Onfleet('<api_key>', 30000) // 在此設定執行逾時參數為30000ms
```

### 金鑰認證
當Onfleet物件成功被創建,表示您的應用程式介面金鑰是符合預期的。您可以嘗試使用verifyKey函式來測試您的金鑰是否合法,authentication這個endpoint會認證您的金鑰,回應為一布林值:
```js
Expand Down
29 changes: 25 additions & 4 deletions lib/Methods.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
const Bottleneck = require('bottleneck');
const fetch = require('node-fetch');
const constants = require('./constants');
Expand All @@ -12,7 +13,6 @@ const {
// Create new rate limiter using defined constants
const limiter = new Bottleneck({
reservoir: constants.LIMITER_RESERVOIR,
reservoirRefreshInterval: constants.LIMITER_REFRESH_INTERVAL,
maxConcurrent: constants.LIMITER_MAX_CONCURRENT,
minTime: constants.LIMITER_MIN_TIME,
});
Expand All @@ -22,11 +22,19 @@ const limiter = new Bottleneck({
const reassignRate = (newRate) => {
if (newRate > 0) {
limiter.updateSettings({
reservoirRefreshAmount: newRate,
reservoir: newRate,
});
}
};

const wait = (ms) => {
console.log('Waiting due to rate limiting');
// eslint-disable-next-line no-new
new Promise((resolve) => {
setTimeout(resolve, ms);
});
};

/**
* The Method Factory
* @desc configures the actual method for each CRUD operations
Expand Down Expand Up @@ -101,8 +109,21 @@ const Methods = (key, api, ...args) => {
timeout: timeoutInMilliseconds,
body: hasBody ? JSON.stringify(body) : undefined,
}).then((res) => {
// On response, update the rate
reassignRate(res.headers.get('x-ratelimit-remaining'));
// On reservoir depletion, we wait 10000ms and reset the rate again (20 req/second limitation)
limiter.on('depleted', (empty) => {
if (!empty) {
wait(constants.LIMITER_WAIT_UPON_DEPLETION).then(() => {
reassignRate(constants.LIMITER_RESERVOIR);
});
}
});
// For every request, we compare the reservoir with the remainding rate limit in the header
limiter.currentReservoir()
.then((reservoir) => {
if (reservoir < res.headers.get('x-ratelimit-remaining')) {
reassignRate(res.headers.get('x-ratelimit-remaining'));
}
});

if (res.ok) {
// Return status code for deletion as the API does, else, return the body of the response
Expand Down
2 changes: 1 addition & 1 deletion lib/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const constants = {
LIMITER_RESERVOIR: 20,
LIMITER_REFRESH_INTERVAL: 250,
LIMITER_WAIT_UPON_DEPLETION: 10000,
LIMITER_MAX_CONCURRENT: 1,
LIMITER_MIN_TIME: 50,
};
Expand Down
7 changes: 5 additions & 2 deletions lib/onfleet.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ resources.Webhooks = require('./resources/Webhooks');
*/

class Onfleet {
constructor(apiKey) {
constructor(apiKey, userTimeout) {
if (!apiKey) {
throw new ValidationError('Onfleet API key not found, please obtain an API key from your organization admin');
} if (userTimeout > 70000) {
throw new ValidationError('User-defined timeout has to be shorter than 70000ms');
} else {
this.apiKey = apiKey;
this.api = {
baseUrl: `${DEFAULT_URL}${DEFAULT_PATH}/${DEFAULT_API_VERSION}`,
timeout: DEFAULT_TIMEOUT,
// eslint-disable-next-line no-unneeded-ternary
timeout: (userTimeout ? userTimeout : DEFAULT_TIMEOUT),
headers: {
'Content-Type': 'application/json',
'User-Agent': `${name}-${version}`,
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onfleet/node-onfleet",
"version": "1.1.1",
"version": "1.2.0",
"description": "Official client library for accessing the Onfleet API",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 9e871f5

Please sign in to comment.