UNPKG

@rushstack/operation-graph

Version:

Library for managing and executing operations in a directed acyclic graph.

49 lines 2.13 kB
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. import { Async, MinimumHeap } from '@rushstack/node-core-library'; import { OperationStatus } from './OperationStatus'; export 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 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 }); }); [this._pushPromise, this._resolvePush] = 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.Aborted)); this._resolvePushDebounced(); }); } _resolvePushDebounced() { if (!this._resolvePushTimeout) { this._resolvePushTimeout = setTimeout(() => { this._resolvePushTimeout = undefined; this._resolvePush(); [this._pushPromise, this._resolvePush] = Async.getSignal(); }); } } } //# sourceMappingURL=WorkQueue.js.map