Refactored http timeout handling.

This commit is contained in:
DebaucheryLibrarian
2021-03-17 02:09:34 +01:00
parent 36a8adbd8c
commit 336b91c872
9 changed files with 147 additions and 72 deletions

View File

@@ -80,20 +80,9 @@ function getLimiter(options = {}, url) {
return limiters[interval][concurrency];
}
async function request(method = 'get', url, body, requestOptions = {}, limiter, timeout) {
async function request(method = 'get', url, body, requestOptions = {}, limiter) {
const http = requestOptions.session || bhttp;
const options = {
...defaultOptions,
...requestOptions,
headers: {
...defaultOptions.headers,
...requestOptions.headers,
},
responseTimeout: requestOptions.responseTimeout || requestOptions.timeout || defaultOptions.timeout,
stream: !!requestOptions.destination,
session: null,
};
const options = requestOptions;
const withProxy = useProxy(url);
@@ -107,8 +96,10 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter,
? http[method](url, body, options)
: http[method](url, options));
timeout.cancel();
return res;
}
async function finalizeResult(res, options) {
if (options.destination) {
// res.on('progress', (bytes, totalBytes) => logger.silly(`Downloaded ${Math.round((bytes / totalBytes) * 100)}% of ${url}`));
@@ -140,21 +131,39 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter,
function getTimeout(options, url) {
return new Promise((resolve, reject, onCancel) => {
const timeoutId = setTimeout(() => {
const timeout = setTimeout(() => {
reject(new Error(`URL ${url} timed out`));
}, (options?.timeout || defaultOptions.timeout) + 10000);
onCancel(() => clearTimeout(timeoutId));
onCancel(() => {
clearTimeout(timeout);
});
});
}
async function scheduleRequest(method = 'get', url, body, options) {
async function scheduleRequest(method = 'get', url, body, requestOptions = {}) {
const options = {
...defaultOptions,
...requestOptions,
headers: {
...defaultOptions.headers,
...requestOptions.headers,
},
responseTimeout: requestOptions.responseTimeout || requestOptions.timeout || defaultOptions.timeout,
stream: !!requestOptions.destination,
session: null,
};
const limiter = getLimiter(options, url);
const timeout = getTimeout(options, url);
const result = await limiter.schedule(() => Promise.race([request(method, url, body, options, limiter, timeout), timeout]));
const result = await limiter.schedule(async () => Promise.race([request(method, url, body, options, limiter), timeout]));
return result;
timeout.cancel();
const curatedResult = await finalizeResult(result, options);
return curatedResult;
}
async function get(url, options) {