@rushstack/operation-graph
Version:
Library for managing and executing operations in a directed acyclic graph.
57 lines • 2.63 kB
JavaScript
;
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkQueue = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const OperationStatus_1 = require("./OperationStatus");
class WorkQueue {
constructor(abortSignal) {
// Sort by priority descending. Thus the comparator returns a negative number if a has higher priority than b.
this._queue = new node_core_library_1.MinimumHeap((a, b) => b.priority - a.priority);
this._abortSignal = abortSignal;
this._abortPromise = abortSignal.aborted
? Promise.resolve()
: new Promise((resolve) => {
abortSignal.addEventListener('abort', () => resolve(), { once: true });
});
// ESLINT: "An array of Promises may be unintentional."
// eslint-disable-next-line @typescript-eslint/no-floating-promises
[this._pushPromise, this._resolvePush] = node_core_library_1.Async.getSignal();
this._resolvePushTimeout = undefined;
}
async *[Symbol.asyncIterator]() {
while (!this._abortSignal.aborted) {
while (this._queue.size > 0) {
const item = this._queue.poll();
yield item.task;
}
await Promise.race([this._pushPromise, this._abortPromise]);
}
}
pushAsync(task, priority) {
return new Promise((resolve, reject) => {
this._queue.push({
task: () => task().then(resolve, reject),
priority
});
// ESLINT: "Promises must be awaited, end with a call to .catch, end with a call to .then ..."
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this._abortPromise.finally(() => resolve(OperationStatus_1.OperationStatus.Aborted));
this._resolvePushDebounced();
});
}
_resolvePushDebounced() {
if (!this._resolvePushTimeout) {
this._resolvePushTimeout = setTimeout(() => {
this._resolvePushTimeout = undefined;
this._resolvePush();
// ESLINT: "An array of Promises may be unintentional."
// eslint-disable-next-line @typescript-eslint/no-floating-promises
[this._pushPromise, this._resolvePush] = node_core_library_1.Async.getSignal();
});
}
}
}
exports.WorkQueue = WorkQueue;
//# sourceMappingURL=WorkQueue.js.map