add and run prettier
This commit is contained in:
@ -1,9 +1,17 @@
|
||||
import {default as createQueue, PRIORITY as QUEUE_PRIORITY} from '../../utils/queue';
|
||||
import {SsrError, SsrTimeoutError} from '../../others/errors'
|
||||
import {SsrHttpRateLimitError, SsrHttpResponseError, SsrNetworkError, SsrNetworkTimeoutError} from '../errors'
|
||||
import {fetchHtml, fetchJson} from '../fetch';
|
||||
import makePendingPromisePool from '../../utils/pending-promises'
|
||||
import {AbortError} from '../../utils/promise'
|
||||
import {
|
||||
default as createQueue,
|
||||
PRIORITY as QUEUE_PRIORITY,
|
||||
} from "../../utils/queue";
|
||||
import { SsrError, SsrTimeoutError } from "../../others/errors";
|
||||
import {
|
||||
SsrHttpRateLimitError,
|
||||
SsrHttpResponseError,
|
||||
SsrNetworkError,
|
||||
SsrNetworkTimeoutError,
|
||||
} from "../errors";
|
||||
import { fetchHtml, fetchJson } from "../fetch";
|
||||
import makePendingPromisePool from "../../utils/pending-promises";
|
||||
import { AbortError } from "../../utils/promise";
|
||||
|
||||
const DEFAULT_RETRIES = 2;
|
||||
|
||||
@ -13,65 +21,91 @@ export const PRIORITY = {
|
||||
BG_HIGH: QUEUE_PRIORITY.NORMAL,
|
||||
BG_NORMAL: QUEUE_PRIORITY.LOW,
|
||||
BG_LOW: QUEUE_PRIORITY.LOWEST,
|
||||
}
|
||||
};
|
||||
|
||||
const resolvePromiseOrWaitForPending = makePendingPromisePool();
|
||||
|
||||
export default (options = {}) => {
|
||||
const {retries, rateLimitTick, ...queueOptions} = {retries: DEFAULT_RETRIES, rateLimitTick: 500, ...options};
|
||||
const { retries, rateLimitTick, ...queueOptions } = {
|
||||
retries: DEFAULT_RETRIES,
|
||||
rateLimitTick: 500,
|
||||
...options,
|
||||
};
|
||||
const queue = createQueue(queueOptions);
|
||||
|
||||
const {add, emitter, ...queueToReturn} = queue;
|
||||
const { add, emitter, ...queueToReturn } = queue;
|
||||
|
||||
let lastRateLimitError = null;
|
||||
let rateLimitTimerId = null;
|
||||
let currentRateLimit = {waiting: 0, remaining: null, limit: null, resetAt: null};
|
||||
let currentRateLimit = {
|
||||
waiting: 0,
|
||||
remaining: null,
|
||||
limit: null,
|
||||
resetAt: null,
|
||||
};
|
||||
|
||||
const rateLimitTicker = () => {
|
||||
const expiresInMs = lastRateLimitError && lastRateLimitError.resetAt ? lastRateLimitError.resetAt - new Date() + 1000 : 0;
|
||||
const expiresInMs =
|
||||
lastRateLimitError && lastRateLimitError.resetAt
|
||||
? lastRateLimitError.resetAt - new Date() + 1000
|
||||
: 0;
|
||||
if (expiresInMs <= 0) {
|
||||
emitter.emit('waiting', {waiting: 0, remaining: null, limit: null, resetAt: null});
|
||||
emitter.emit("waiting", {
|
||||
waiting: 0,
|
||||
remaining: null,
|
||||
limit: null,
|
||||
resetAt: null,
|
||||
});
|
||||
|
||||
if (rateLimitTimerId) clearTimeout(rateLimitTimerId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const {remaining, limit, resetAt} = lastRateLimitError;
|
||||
emitter.emit('waiting', {waiting: expiresInMs, remaining, limit, resetAt});
|
||||
const { remaining, limit, resetAt } = lastRateLimitError;
|
||||
emitter.emit("waiting", {
|
||||
waiting: expiresInMs,
|
||||
remaining,
|
||||
limit,
|
||||
resetAt,
|
||||
});
|
||||
|
||||
if (rateLimitTimerId) clearTimeout(rateLimitTimerId);
|
||||
rateLimitTimerId = setTimeout(rateLimitTicker, rateLimitTick);
|
||||
}
|
||||
};
|
||||
|
||||
const retriedFetch = async (fetchFunc, url, options, priority = PRIORITY.FG_LOW) => {
|
||||
const retriedFetch = async (
|
||||
fetchFunc,
|
||||
url,
|
||||
options,
|
||||
priority = PRIORITY.FG_LOW,
|
||||
) => {
|
||||
for (let i = 0; i <= retries; i++) {
|
||||
try {
|
||||
return await add(async () => {
|
||||
if (lastRateLimitError) {
|
||||
await lastRateLimitError.waitBeforeRetry();
|
||||
if (lastRateLimitError) {
|
||||
await lastRateLimitError.waitBeforeRetry();
|
||||
|
||||
lastRateLimitError = null;
|
||||
}
|
||||
lastRateLimitError = null;
|
||||
}
|
||||
|
||||
return fetchFunc(url, options)
|
||||
.then(response => {
|
||||
currentRateLimit = {...response.rateLimit, waiting: 0};
|
||||
return fetchFunc(url, options)
|
||||
.then((response) => {
|
||||
currentRateLimit = { ...response.rateLimit, waiting: 0 };
|
||||
|
||||
return response;
|
||||
})
|
||||
.catch(err => {
|
||||
if (err instanceof SsrTimeoutError) throw new SsrNetworkTimeoutError(err.timeout);
|
||||
return response;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err instanceof SsrTimeoutError)
|
||||
throw new SsrNetworkTimeoutError(err.timeout);
|
||||
|
||||
throw err;
|
||||
})
|
||||
},
|
||||
priority,
|
||||
)
|
||||
throw err;
|
||||
});
|
||||
}, priority);
|
||||
} catch (err) {
|
||||
if (err instanceof SsrHttpResponseError) {
|
||||
const {remaining, limit, resetAt} = err;
|
||||
currentRateLimit = {waiting: 0, remaining, limit, resetAt};
|
||||
const { remaining, limit, resetAt } = err;
|
||||
currentRateLimit = { waiting: 0, remaining, limit, resetAt };
|
||||
}
|
||||
|
||||
if (err instanceof SsrNetworkError) {
|
||||
@ -79,7 +113,13 @@ export default (options = {}) => {
|
||||
if (!shouldRetry || i === retries) throw err;
|
||||
|
||||
if (err instanceof SsrHttpRateLimitError) {
|
||||
if (err.remaining <= 0 && err.resetAt && (!lastRateLimitError || !lastRateLimitError.resetAt || lastRateLimitError.resetAt < err.resetAt)) {
|
||||
if (
|
||||
err.remaining <= 0 &&
|
||||
err.resetAt &&
|
||||
(!lastRateLimitError ||
|
||||
!lastRateLimitError.resetAt ||
|
||||
lastRateLimitError.resetAt < err.resetAt)
|
||||
) {
|
||||
lastRateLimitError = err;
|
||||
|
||||
rateLimitTicker();
|
||||
@ -95,11 +135,17 @@ export default (options = {}) => {
|
||||
}
|
||||
}
|
||||
|
||||
throw new SsrError('Unknown error');
|
||||
}
|
||||
throw new SsrError("Unknown error");
|
||||
};
|
||||
|
||||
const queuedFetchJson = async (url, options, priority = PRIORITY.FG_LOW) => resolvePromiseOrWaitForPending(url, () => retriedFetch(fetchJson, url, options, priority));
|
||||
const queuedFetchHtml = async (url, options, priority = PRIORITY.FG_LOW) => resolvePromiseOrWaitForPending(url, () => retriedFetch(fetchHtml, url, options, priority));
|
||||
const queuedFetchJson = async (url, options, priority = PRIORITY.FG_LOW) =>
|
||||
resolvePromiseOrWaitForPending(url, () =>
|
||||
retriedFetch(fetchJson, url, options, priority),
|
||||
);
|
||||
const queuedFetchHtml = async (url, options, priority = PRIORITY.FG_LOW) =>
|
||||
resolvePromiseOrWaitForPending(url, () =>
|
||||
retriedFetch(fetchHtml, url, options, priority),
|
||||
);
|
||||
|
||||
const getRateLimit = () => currentRateLimit;
|
||||
|
||||
@ -108,5 +154,5 @@ export default (options = {}) => {
|
||||
fetchHtml: queuedFetchHtml,
|
||||
getRateLimit,
|
||||
...queueToReturn,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user