Skip to content

Commit

Permalink
Added Retry-After support and adjustable slot interval to fetchJson.
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Jul 15, 2020
1 parent 6fa853b commit 7d43545
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions packages/web/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type ConnectionInfo = {
allowInsecureAuthentication?: boolean,

throttleLimit?: number,
throttleSlotInterval?: number;
throttleCallback?: (attempt: number, url: string) => Promise<boolean>,

timeout?: number,
Expand Down Expand Up @@ -66,6 +67,9 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
"invalid connection throttle limit", "connection.throttleLimit", attemptLimit);

const throttleCallback = ((typeof(connection) === "object") ? connection.throttleCallback: null);
const throttleSlotInterval = ((typeof(connection) === "object" && typeof(connection.throttleSlotInterval) === "number") ? connection.throttleSlotInterval: 100);
logger.assertArgument((throttleSlotInterval > 0 && (throttleSlotInterval % 1) === 0),
"invalid connection throttle slot interval", "connection.throttleSlotInterval", throttleSlotInterval);

const headers: { [key: string]: Header } = { };

Expand Down Expand Up @@ -168,16 +172,24 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
try {
response = await getUrl(url, options);

// Exponential back-off throttling (interval = 100ms)
// Exponential back-off throttling
if (response.statusCode === 429 && attempt < attemptLimit) {
let tryAgain = true;
if (throttleCallback) {
tryAgain = await throttleCallback(attempt, url);
}

if (tryAgain) {
const timeout = 100 * parseInt(String(Math.random() * Math.pow(2, attempt)));
await staller(timeout);
let stall = 0;

const retryAfter = response.headers["retry-after"];
if (typeof(retryAfter) === "string" && retryAfter.match(/^[1-9][0-9]*$/)) {
stall = parseInt(retryAfter) * 1000;
} else {
stall = throttleSlotInterval * parseInt(String(Math.random() * Math.pow(2, attempt)));
}

await staller(stall);
continue;
}
}
Expand Down Expand Up @@ -241,7 +253,7 @@ export function fetchJson(connection: string | ConnectionInfo, json?: string, pr
}

if (tryAgain) {
const timeout = 100 * parseInt(String(Math.random() * Math.pow(2, attempt)));
const timeout = throttleSlotInterval * parseInt(String(Math.random() * Math.pow(2, attempt)));
await staller(timeout);
continue;
}
Expand Down

0 comments on commit 7d43545

Please sign in to comment.