ayakashi
Version:
The next generation web scraping framework
88 lines (87 loc) • 3.83 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.attachRetry = void 0;
const async_1 = require("async");
const backoff_1 = require("backoff");
const opLog_1 = require("../../opLog/opLog");
const path_1 = require("path");
function attachRetry(ayakashiInstance) {
const opLog = opLog_1.getOpLog();
//@ts-ignore
ayakashiInstance.retry = function (task, retries = 10) {
return __awaiter(this, void 0, void 0, function* () {
if (!task || typeof task !== "function") {
throw new Error("<retry> requires a function to run");
}
if (retries <= 0) {
//tslint:disable no-parameter-reassignment
retries = 10;
//tslint:enable
}
let retried = 0;
const strategy = new backoff_1.ExponentialStrategy({
randomisationFactor: 0.5,
initialDelay: 500,
maxDelay: 5000,
factor: 2
});
const errForStack = new Error();
Error.captureStackTrace(errForStack, ayakashiInstance.retry);
let filename = "";
if (errForStack && errForStack.stack) {
const stackMatch = errForStack.stack.match(/\/([\/\w-_\.]+\.js):(\d*):(\d*)/);
if (stackMatch && stackMatch[0]) {
filename = stackMatch[0].split(path_1.sep).pop() || "";
}
}
return new Promise(function (resolve, reject) {
async_1.retry({
times: retries,
interval: function () {
return strategy.next();
}
}, function (cb) {
let taskResult;
taskResult = task(retried + 1);
if (taskResult instanceof Promise) {
taskResult
.then(function (result) {
cb(null, result);
})
.catch(function (err) {
retried += 1;
console.error(err);
if (retried < retries) {
opLog.warn(`operation ${filename} will be retried -`, `retries: ${retried}/${retries}`);
}
else {
opLog.error(`${retries} retries reached for ${filename} - operation will fail`);
}
cb(err);
});
}
else {
reject(new Error("<retry> requires an async function that returns a promise"));
}
}, function (err, result) {
if (err) {
reject(err);
}
else {
resolve(result);
}
});
});
});
};
}
exports.attachRetry = attachRetry;