openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
162 lines (130 loc) • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.reachedMaxAttempts = reachedMaxAttempts;
exports.queueForRetry = queueForRetry;
exports.setupAgenda = setupAgenda;
var _winston = _interopRequireDefault(require("winston"));
var _moment = _interopRequireDefault(require("moment"));
var _autoRetry = require("./model/autoRetry");
var _tasks = require("./model/tasks");
var Channels = _interopRequireWildcard(require("./model/channels"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
ChannelModel
} = Channels;
function reachedMaxAttempts(tx, channel) {
return channel.autoRetryMaxAttempts != null && channel.autoRetryMaxAttempts > 0 && tx.autoRetryAttempt >= channel.autoRetryMaxAttempts;
}
async function queueForRetry(tx) {
const retry = new _autoRetry.AutoRetryModel({
transactionID: tx._id,
channelID: tx.channelID,
requestTimestamp: tx.request.timestamp
});
try {
await retry.save();
} catch (err) {
_winston.default.error(`Failed to queue transaction ${tx._id} for auto retry: ${err}`);
}
}
const getChannels = callback => ChannelModel.find({
autoRetryEnabled: true,
status: 'enabled'
}, callback);
function popTransactions(channel, callback) {
const to = (0, _moment.default)().subtract(channel.autoRetryPeriodMinutes - 1, 'minutes');
const query = {
$and: [{
channelID: channel._id
}, {
requestTimestamp: {
$lte: to.toDate()
}
}]
};
_winston.default.debug(`Executing query autoRetry.findAndRemove(${JSON.stringify(query)})`);
_autoRetry.AutoRetryModel.find(query, (err, transactions) => {
if (err) {
return callback(err);
}
if (transactions.length === 0) {
return callback(null, []);
}
_autoRetry.AutoRetryModel.deleteOne({
_id: {
$in: transactions.map(t => t._id)
}
}, err => {
if (err) {
return callback(err);
}
return callback(null, transactions);
});
});
}
function createRerunTask(transactionIDs, callback) {
_winston.default.info(`Rerunning failed transactions: ${transactionIDs}`);
const task = new _tasks.TaskModel({
transactions: transactionIDs.map(t => ({
tid: t
})),
totalTransactions: transactionIDs.length,
remainingTransactions: transactionIDs.length,
user: 'internal'
});
task.save(err => {
if (err) {
_winston.default.error(err);
}
return callback();
});
}
function autoRetryTask(job, done) {
const _taskStart = new Date();
const transactionsToRerun = [];
getChannels((err, channels) => {
if (err) {
return done(err);
}
const promises = channels.map(channel => {
return new Promise((resolve, reject) => {
popTransactions(channel, (err, transactions) => {
if (err) {
_winston.default.error(err);
return reject(err);
} else if (transactions != null) {
const tranIDs = transactions.map(r => r.transactionID);
transactionsToRerun.push(...tranIDs);
}
return resolve();
});
});
});
Promise.all(promises).then(() => {
function end() {
_winston.default.debug(`Auto retry task total time: ${new Date() - _taskStart} ms`);
return done();
}
if (transactionsToRerun.length > 0) {
return createRerunTask(transactionsToRerun, end);
} else {
end();
}
}).catch(done);
});
}
function setupAgenda(agenda) {
agenda.define('auto retry failed transactions', (job, done) => autoRetryTask(job, done));
return agenda.every('1 minutes', 'auto retry failed transactions');
}
if (process.env.NODE_ENV === 'test') {
exports.getChannels = getChannels;
exports.popTransactions = popTransactions;
exports.createRerunTask = createRerunTask;
exports.autoRetryTask = autoRetryTask;
}
//# sourceMappingURL=autoRetry.js.map