Skip to content

Commit

Permalink
Merge pull request #2 from CoSchedule/jfm-add_request_retry_feature
Browse files Browse the repository at this point in the history
[CHORE] Add ability to internally retry /oauth/token calls.
  • Loading branch information
atalian authored Nov 27, 2018
2 parents bef96cc + 06e4528 commit 98e51df
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
17 changes: 15 additions & 2 deletions auth.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
const request = require('request-promise');
const { requestWithRetries, isRequestError, isStatusCodeError } = require('./requestPromiseUtils');

const shouldRetry = (err, nextTryCount) => {
if (nextTryCount > 5) {
return false;
}

return isRequestError(err) || (isStatusCodeError(err) && (err.statusCode === 403));
};

const computeRetryDelay = (err, nextTryCount) => (Math.round(Math.random() * 100) + (nextTryCount * 750));

module.exports = (zuoraClient) => {
let accessToken;
Expand All @@ -22,7 +32,10 @@ module.exports = (zuoraClient) => {
json: true,
};

const response = await request(options);
const response = await requestWithRetries(options, shouldRetry, computeRetryDelay);
if (!response) {
throw new Error('ZuoraJS: Auth: Empty Response');
}

accessToken = response.access_token;
renewalTime = Date.now() + ((response.expires_in * 1000) - 60000);
Expand Down
34 changes: 34 additions & 0 deletions requestPromiseUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const requestPromise = require('request-promise');
const requestPromiseErrors = require('request-promise/errors');

const requestWithRetries = async (requestOptions, shouldRetry, computeRetryDelay) => {
const makeRequest = async (tryCount) => {
let response;
try {
response = await requestPromise(requestOptions);
} catch (err) {
if (!shouldRetry || !shouldRetry(err, tryCount)) {
throw err;
}

const nextTryCount = tryCount + 1;
const retryDelay = await ((computeRetryDelay && computeRetryDelay(err, nextTryCount)) || 1000);
await new Promise((resolve) => setTimeout(resolve, retryDelay));

response = makeRequest(nextTryCount);
}

return response;
};

return makeRequest(1);
};

const isRequestError = (err) => (err instanceof requestPromiseErrors.RequestError);
const isStatusCodeError = (err) => (err instanceof requestPromiseErrors.StatusCodeError);

module.exports = {
requestWithRetries,
isRequestError,
isStatusCodeError,
};

0 comments on commit 98e51df

Please sign in to comment.