run-exclusive
Version:
Generate functions that do not allow parallel executions
281 lines • 10.5 kB
JavaScript
;
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
exports.__esModule = true;
exports.buildMethodCb = exports.buildCb = exports.getPrComplete = exports.isRunning = exports.cancelAllQueuedCalls = exports.getQueuedCallCount = exports.buildMethod = exports.build = exports.createGroupRef = void 0;
// @denoify-line-ignore
var WeakMap_1 = require("minimal-polyfills/WeakMap");
var ExecQueue = /** @class */ (function () {
function ExecQueue() {
this.queuedCalls = [];
this.isRunning = false;
this.prComplete = Promise.resolve();
}
//TODO: move where it is used.
ExecQueue.prototype.cancelAllQueuedCalls = function () {
var n;
this.queuedCalls.splice(0, n = this.queuedCalls.length);
return n;
};
return ExecQueue;
}());
var globalContext = {};
var clusters = new WeakMap_1.Polyfill();
//console.log("Map version");
//export const clusters = new Map<Object, Map<GroupRef,ExecQueue>>();
function getOrCreateExecQueue(context, groupRef) {
var execQueueByGroup = clusters.get(context);
if (!execQueueByGroup) {
execQueueByGroup = new WeakMap_1.Polyfill();
clusters.set(context, execQueueByGroup);
}
var execQueue = execQueueByGroup.get(groupRef);
if (!execQueue) {
execQueue = new ExecQueue();
execQueueByGroup.set(groupRef, execQueue);
}
return execQueue;
}
function createGroupRef() {
return new Array(0);
}
exports.createGroupRef = createGroupRef;
function build() {
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
switch (inputs.length) {
case 1: return buildFnPromise(true, createGroupRef(), inputs[0]);
case 2: return buildFnPromise(true, inputs[0], inputs[1]);
}
}
exports.build = build;
function buildMethod() {
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
switch (inputs.length) {
case 1: return buildFnPromise(false, createGroupRef(), inputs[0]);
case 2: return buildFnPromise(false, inputs[0], inputs[1]);
}
}
exports.buildMethod = buildMethod;
/**
*
* Get the number of queued call of a run-exclusive function.
* Note that if you call a runExclusive function and call this
* directly after it will return 0 as there is one function call
* execution ongoing but 0 queued.
*
* The classInstanceObject parameter is to provide only for the run-exclusive
* function created with 'buildMethod[Cb].
*
* */
function getQueuedCallCount(runExclusiveFunction, classInstanceObject) {
var execQueue = getExecQueueByFunctionAndContext(runExclusiveFunction, classInstanceObject);
return execQueue ? execQueue.queuedCalls.length : 0;
}
exports.getQueuedCallCount = getQueuedCallCount;
/**
*
* Cancel all queued calls of a run-exclusive function.
* Note that the current running call will not be cancelled.
*
* The classInstanceObject parameter is to provide only for the run-exclusive
* function created with 'buildMethod[Cb].
*
*/
function cancelAllQueuedCalls(runExclusiveFunction, classInstanceObject) {
var execQueue = getExecQueueByFunctionAndContext(runExclusiveFunction, classInstanceObject);
return execQueue ? execQueue.cancelAllQueuedCalls() : 0;
}
exports.cancelAllQueuedCalls = cancelAllQueuedCalls;
/**
* Tell if a run-exclusive function has an instance of it's call currently being
* performed.
*
* The classInstanceObject parameter is to provide only for the run-exclusive
* function created with 'buildMethod[Cb].
*/
function isRunning(runExclusiveFunction, classInstanceObject) {
var execQueue = getExecQueueByFunctionAndContext(runExclusiveFunction, classInstanceObject);
return execQueue ? execQueue.isRunning : false;
}
exports.isRunning = isRunning;
/**
* Return a promise that resolve when all the current queued call of a runExclusive functions
* have completed.
*
* The classInstanceObject parameter is to provide only for the run-exclusive
* function created with 'buildMethod[Cb].
*/
function getPrComplete(runExclusiveFunction, classInstanceObject) {
var execQueue = getExecQueueByFunctionAndContext(runExclusiveFunction, classInstanceObject);
return execQueue ? execQueue.prComplete : Promise.resolve();
}
exports.getPrComplete = getPrComplete;
var groupByRunExclusiveFunction = new WeakMap_1.Polyfill();
function getExecQueueByFunctionAndContext(runExclusiveFunction, context) {
if (context === void 0) { context = globalContext; }
var groupRef = groupByRunExclusiveFunction.get(runExclusiveFunction);
if (!groupRef) {
throw Error("Not a run exclusiveFunction");
}
var execQueueByGroup = clusters.get(context);
if (!execQueueByGroup) {
return undefined;
}
return execQueueByGroup.get(groupRef);
}
function buildFnPromise(isGlobal, groupRef, fun) {
var execQueue;
var runExclusiveFunction = (function () {
var _this = this;
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
if (!isGlobal) {
if (!(this instanceof Object)) {
throw new Error("Run exclusive, <this> should be an object");
}
execQueue = getOrCreateExecQueue(this, groupRef);
}
return new Promise(function (resolve, reject) {
var onPrCompleteResolve;
execQueue.prComplete = new Promise(function (resolve) {
return onPrCompleteResolve = function () { return resolve(); };
});
var onComplete = function (result) {
onPrCompleteResolve();
execQueue.isRunning = false;
if (execQueue.queuedCalls.length) {
execQueue.queuedCalls.shift()();
}
if ("data" in result) {
resolve(result.data);
}
else {
reject(result.reason);
}
};
(function callee() {
var _this = this;
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
if (execQueue.isRunning) {
execQueue.queuedCalls.push(function () { return callee.apply(_this, inputs); });
return;
}
execQueue.isRunning = true;
try {
fun.apply(this, inputs)
.then(function (data) { return onComplete({ data: data }); })["catch"](function (reason) { return onComplete({ reason: reason }); });
}
catch (error) {
onComplete({ "reason": error });
}
}).apply(_this, inputs);
});
});
if (isGlobal) {
execQueue = getOrCreateExecQueue(globalContext, groupRef);
}
groupByRunExclusiveFunction.set(runExclusiveFunction, groupRef);
return runExclusiveFunction;
}
function buildCb() {
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
switch (inputs.length) {
case 1: return buildFnCallback(true, createGroupRef(), inputs[0]);
case 2: return buildFnCallback(true, inputs[0], inputs[1]);
}
}
exports.buildCb = buildCb;
function buildMethodCb() {
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
switch (inputs.length) {
case 1: return buildFnCallback(false, createGroupRef(), inputs[0]);
case 2: return buildFnCallback(false, inputs[0], inputs[1]);
}
}
exports.buildMethodCb = buildMethodCb;
function buildFnCallback(isGlobal, groupRef, fun) {
var execQueue;
var runExclusiveFunction = (function () {
var _this = this;
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
if (!isGlobal) {
if (!(this instanceof Object)) {
throw new Error("Run exclusive, <this> should be an object");
}
execQueue = getOrCreateExecQueue(this, groupRef);
}
var callback = undefined;
if (inputs.length && typeof inputs[inputs.length - 1] === "function") {
callback = inputs.pop();
}
var onPrCompleteResolve;
execQueue.prComplete = new Promise(function (resolve) {
return onPrCompleteResolve = function () { return resolve(); };
});
var onComplete = function () {
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
onPrCompleteResolve();
execQueue.isRunning = false;
if (execQueue.queuedCalls.length) {
execQueue.queuedCalls.shift()();
}
if (callback) {
callback.apply(_this, inputs);
}
};
onComplete.hasCallback = !!callback;
(function callee() {
var _this = this;
var inputs = [];
for (var _i = 0; _i < arguments.length; _i++) {
inputs[_i] = arguments[_i];
}
if (execQueue.isRunning) {
execQueue.queuedCalls.push(function () { return callee.apply(_this, inputs); });
return;
}
execQueue.isRunning = true;
try {
fun.apply(this, __spreadArrays(inputs, [onComplete]));
}
catch (error) {
error.message += " ( This exception should not have been thrown, miss use of run-exclusive buildCb )";
throw error;
}
}).apply(this, inputs);
});
if (isGlobal) {
execQueue = getOrCreateExecQueue(globalContext, groupRef);
}
groupByRunExclusiveFunction.set(runExclusiveFunction, groupRef);
return runExclusiveFunction;
}
//# sourceMappingURL=runExclusive.js.map