UNPKG

@buttercup/channel-queue

Version:

A queue management library with channels

85 lines (84 loc) 2.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParallelChannel = void 0; const Channel_1 = require("./Channel"); /** * ParallelChannel class (queue) * @augments Channel */ class ParallelChannel extends Channel_1.Channel { constructor(name) { super(name); this._parallelism = 2; this._runningTasks = []; this.canRunAcrossTaskTypes = false; } /** * Whether the queue is empty or not * @type {Boolean} * @readonly */ get isEmpty() { return super.isEmpty && this._runningTasks.length <= 0; } /** * The amount of allowed parallel executed tasks * @type {Number} * @readonly */ get parallelism() { return this._parallelism; } /** * Get the currently running tasks * @type {Array<Task>} * @readonly */ get runningTasks() { return this._runningTasks; } set parallelism(count) { const newCount = Math.max(count, 1); this._parallelism = newCount; } _runNextItem() { const stopChannel = () => { this.isRunning = false; this.emit("stopped"); }; if (this.runningTasks.length === 0 && this.tasks.length === 0) { stopChannel(); return; } let itemsToRun = this.parallelism - this.runningTasks.length; if (itemsToRun <= 0) { return; } while (itemsToRun > 0) { // First check to see if any other tasks are running, and whether or not // we're allowed to run tasks of different priorities at the same time if (!this.canRunAcrossTaskTypes && this.runningTasks.length > 0 && this.tasks.length > 0) { const runningType = this.runningTasks[0].type; const nextType = this.tasks[0].type; if (runningType !== nextType) { // Next item is not of the same type, so we'll skip this round return; } } itemsToRun -= 1; const item = this.retrieveNextItem(); if (!item) { // No item, skip return; } this.runningTasks.push(item); item.execute().then(() => { this.runningTasks.splice(this.runningTasks.indexOf(item), 1); this._runNextItem(); }); } } } exports.ParallelChannel = ParallelChannel;