topkat-utils
Version:
A comprehensive collection of TypeScript/JavaScript utility functions for common programming tasks. Includes validation, object manipulation, date handling, string formatting, and more. Zero dependencies, fully typed, and optimized for performance.
73 lines • 3.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.waitForTransaction = exports.removeItemFromQueue = exports.transaction = void 0;
//----------------------------------------
// TRANSACTION
//----------------------------------------
const isset_1 = require("./isset");
const logger_utils_1 = require("./logger-utils");
const timer_utils_1 = require("./timer-utils");
const transactionRunning = { __default: false };
const queue = { __default: [] };
/** Allow to perform async functions in a defined order
* This adds the callback to a queue and is resolved when ALL previous callbacks with same name are executed
* Use it like: await transaction('nameOfTheFlow', async () => { ...myFunction })
* @param {String|Function} name name for the actions that should never happen concurrently
* @param {Function} asyncCallback
* @param {Number} timeout default: 120000 (120s) will throw an error if transaction time is higher that this amount of ms
* @returns {Promise}
*/
async function transaction(name, asyncCallback, timeout = 120000, doNotThrow = false) {
if (typeof name === 'function') {
asyncCallback = name;
name = '__default';
}
if (!(0, isset_1.isset)(queue[name]))
queue[name] = [];
if (!(0, isset_1.isset)(transactionRunning[name]))
transactionRunning[name] = false;
return await new Promise((resolve, reject) => {
if (doNotThrow)
reject = logger_utils_1.C.error;
queue[name].push(async () => {
let to;
try {
to = setTimeout(() => {
logger_utils_1.C.warning('Transaction Timeout'); // in case not catched
reject(new Error('transactionTimeout'));
}, timeout);
const res = await asyncCallback();
clearTimeout(to);
resolve(res);
}
catch (err) {
clearTimeout(to);
reject(err);
}
});
removeItemFromQueue(name);
});
}
exports.transaction = transaction;
async function removeItemFromQueue(name) {
if (transactionRunning[name] === true)
return; // v
transactionRunning[name] = true; // A A /\
while (queue[name].length)
await queue[name].shift()(); // ||
transactionRunning[name] = false; // \==/_______||
} // l ____ *|
exports.removeItemFromQueue = removeItemFromQueue;
// 11 11
/** Wait for a transaction to complete without creating a new transaction */
async function waitForTransaction(transactionName, forceReleaseInSeconds = 30) {
let brk = false;
setTimeout(() => brk = true, forceReleaseInSeconds * 1000);
while ((0, isset_1.isset)(transactionRunning[transactionName]) && transactionRunning[transactionName] === true) {
if (brk)
break;
await (0, timer_utils_1.timeout)(15);
}
}
exports.waitForTransaction = waitForTransaction;
//# sourceMappingURL=transaction-utils.js.map