UNPKG

@zowe/imperative

Version:
133 lines 5.89 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Queue = void 0; const constants_1 = require("../../../constants"); const error_1 = require("../../../error"); class Queue { constructor(options) { this.defaultQueue = "default"; this.mQueueTimeout = constants_1.Constants.MAX_SIGNED_32BIT_NUMBER; this.mMaxConcurrentRequests = constants_1.Constants.MAX_SIGNED_32BIT_NUMBER; this.mQueue = {}; if (options) { this.setThrottlingOptions(options); } this.createQueue(); } /** * Changes an existing request queue's throttling options. * @param options - The throttling options to apply to the request queue. * @throws {ImperativeError} - when the options provided are out of bounds. */ setThrottlingOptions(options) { // Overwrite the throttling options. // Timeout changes will only apply to future requests, not ones in progress. if (options.maxConcurrentRequests != null) { if (options.maxConcurrentRequests < 0) { throw new error_1.ImperativeError({ msg: "Maximum concurrent requests cannot be less than zero." }); } else if (options.maxConcurrentRequests == 0) { this.mMaxConcurrentRequests = constants_1.Constants.MAX_SIGNED_32BIT_NUMBER; } else { this.mMaxConcurrentRequests = options.maxConcurrentRequests; } } if (options.queueTimeout != null) { if (options.queueTimeout <= 0 || options.queueTimeout > constants_1.Constants.MAX_SIGNED_32BIT_NUMBER) { throw new error_1.ImperativeError({ msg: "Queue timeout must be between 0 and " + constants_1.Constants.MAX_SIGNED_32BIT_NUMBER.toString() + "." }); } this.mQueueTimeout = options.queueTimeout; } } /** * Add a promise to the queue * @param promiseFunction The promise, bound with all arguments, to execute on its turn in the queue. * @param poolId The queue pool that the promise should execute against * @returns The promise of the promiseFunction */ enqueue(promiseFunction, poolId) { return new Promise((resolve, reject) => { if (!poolId) { poolId = this.defaultQueue; } // Create and use custom pool if pool is specified. if (!this.mQueue[poolId]) { this.createQueue(poolId); } // Create the request, and attach the timeout. const request = { func: promiseFunction, timeout: setTimeout(() => { request.timedOut = true; }, this.mQueueTimeout), timedOut: false, resolve, reject }; // Queue the request and run dequeue. this.mQueue[poolId].requestPool.push(request); this.dequeue(poolId); }); } /** * Removes an item from the queue, checks if it times out, and executes the promise if valid * @param queue The pool of promises to execute against */ dequeue(queue) { return __awaiter(this, void 0, void 0, function* () { // Exit if there are no more requests in the queue or we are at the maximum number of requests in progress. if (!this.mQueue[queue].requestPool.length || this.mQueue[queue].inProgress >= this.mMaxConcurrentRequests) { return; } // Get the next item to process, and increment the inProgress counter. const execItem = this.mQueue[queue].requestPool.shift(); this.mQueue[queue].inProgress++; try { clearTimeout(execItem.timeout); // Try to process the item. If it timed out in the queue, throw an error and pick up the next one. if (execItem.timedOut) { throw new error_1.ImperativeError({ msg: "Request timed out while in the request queue." }); } const result = yield execItem.func(); execItem.resolve(result); } catch (err) { execItem.reject(err); } finally { // Let's go again! this.mQueue[queue].inProgress--; this.dequeue(queue); } }); } /** * Creates a new queue with the provided name. If none is provided, creates a "default" queue/ * @param name The name of the queue to create */ createQueue(name = this.defaultQueue) { if (!this.mQueue[name]) { this.mQueue[name] = { inProgress: 0, requestPool: [] }; } // Handle check again in case of race condition } } exports.Queue = Queue; //# sourceMappingURL=Queue.js.map