125 lines
5.2 KiB
JavaScript
125 lines
5.2 KiB
JavaScript
import { __awaiter, __generator } from "tslib";
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { E_TIMEOUT } from './errors';
|
|
export function withTimeout(sync, timeout, timeoutError) {
|
|
var _this = this;
|
|
if (timeoutError === void 0) { timeoutError = E_TIMEOUT; }
|
|
return {
|
|
acquire: function (weightOrPriority, priority) {
|
|
var weight;
|
|
if (isSemaphore(sync)) {
|
|
weight = weightOrPriority;
|
|
}
|
|
else {
|
|
weight = undefined;
|
|
priority = weightOrPriority;
|
|
}
|
|
if (weight !== undefined && weight <= 0) {
|
|
throw new Error("invalid weight ".concat(weight, ": must be positive"));
|
|
}
|
|
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
|
|
var isTimeout, handle, ticket, release, e_1;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
isTimeout = false;
|
|
handle = setTimeout(function () {
|
|
isTimeout = true;
|
|
reject(timeoutError);
|
|
}, timeout);
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, , 4]);
|
|
return [4 /*yield*/, (isSemaphore(sync)
|
|
? sync.acquire(weight, priority)
|
|
: sync.acquire(priority))];
|
|
case 2:
|
|
ticket = _a.sent();
|
|
if (isTimeout) {
|
|
release = Array.isArray(ticket) ? ticket[1] : ticket;
|
|
release();
|
|
}
|
|
else {
|
|
clearTimeout(handle);
|
|
resolve(ticket);
|
|
}
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
e_1 = _a.sent();
|
|
if (!isTimeout) {
|
|
clearTimeout(handle);
|
|
reject(e_1);
|
|
}
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
}); });
|
|
},
|
|
runExclusive: function (callback, weight, priority) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var release, ticket;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
release = function () { return undefined; };
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, , 7, 8]);
|
|
return [4 /*yield*/, this.acquire(weight, priority)];
|
|
case 2:
|
|
ticket = _a.sent();
|
|
if (!Array.isArray(ticket)) return [3 /*break*/, 4];
|
|
release = ticket[1];
|
|
return [4 /*yield*/, callback(ticket[0])];
|
|
case 3: return [2 /*return*/, _a.sent()];
|
|
case 4:
|
|
release = ticket;
|
|
return [4 /*yield*/, callback()];
|
|
case 5: return [2 /*return*/, _a.sent()];
|
|
case 6: return [3 /*break*/, 8];
|
|
case 7:
|
|
release();
|
|
return [7 /*endfinally*/];
|
|
case 8: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
},
|
|
release: function (weight) {
|
|
sync.release(weight);
|
|
},
|
|
cancel: function () {
|
|
return sync.cancel();
|
|
},
|
|
waitForUnlock: function (weightOrPriority, priority) {
|
|
var weight;
|
|
if (isSemaphore(sync)) {
|
|
weight = weightOrPriority;
|
|
}
|
|
else {
|
|
weight = undefined;
|
|
priority = weightOrPriority;
|
|
}
|
|
if (weight !== undefined && weight <= 0) {
|
|
throw new Error("invalid weight ".concat(weight, ": must be positive"));
|
|
}
|
|
return new Promise(function (resolve, reject) {
|
|
var handle = setTimeout(function () { return reject(timeoutError); }, timeout);
|
|
(isSemaphore(sync)
|
|
? sync.waitForUnlock(weight, priority)
|
|
: sync.waitForUnlock(priority)).then(function () {
|
|
clearTimeout(handle);
|
|
resolve();
|
|
});
|
|
});
|
|
},
|
|
isLocked: function () { return sync.isLocked(); },
|
|
getValue: function () { return sync.getValue(); },
|
|
setValue: function (value) { return sync.setValue(value); },
|
|
};
|
|
}
|
|
function isSemaphore(sync) {
|
|
return sync.getValue !== undefined;
|
|
}
|