UNPKG

yqueue

Version:

Yet another concurrent task queue

110 lines 3.46 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.YBatch = exports.YBatchErrors = void 0; const y_queue_1 = __importDefault(require("./y-queue")); class YBatchErrors extends Error { constructor(errors) { var _a; super(`Batch failed with ${errors.length} errors.`); this.errors = errors; this.name = new.target.name; let s = (_a = this.stack) !== null && _a !== void 0 ? _a : super.toString(); s += '\nwrapped errors:'; this.errors.forEach((e, i) => { s += `\n#${i}\n${e.stack}`; }); this.stack = s; } toString() { let s = super.toString(); s += '\nwrapped errors:'; for (const e of this.errors) { s += '\n\t' + e.toString(); } return s; } } exports.YBatchErrors = YBatchErrors; class YBatch { constructor(options) { this.options = options; this.errors = []; this.failFastWaits = []; this.allSettledWaits = []; this.running = 0; this.queue = new y_queue_1.default({ concurrency: options.concurrency, }); this.maxQueueLength = options.maxQueueLength !== undefined && options.maxQueueLength > 0 ? options.maxQueueLength : this.queue.concurrency; } static isYBatchError(e) { return e instanceof YBatchErrors; } async add(fn, options) { this.running++; await this.queue.onQueueSizeLessThan(this.maxQueueLength); let error = null; const task = this.queue.run(fn, options).catch(e => (error = e)); setImmediate(async () => { await task; if (error !== null) { this.errors.push(error); if (this.failFastWaits.length > 0) { this.failFastWaits.forEach(ack => { ack(this.errors[0]); }); this.failFastWaits = []; } } this.running--; if (this.running === 0) { this.allSettledWaits.forEach(ack => { ack(this.errors); }); this.allSettledWaits = []; this.failFastWaits.forEach(ack => { ack(this.errors[0]); }); this.failFastWaits = []; } }); } async failFast() { if (this.errors.length > 0) { throw this.errors[0]; } if (this.running === 0) { return; } return new Promise((f, r) => { this.failFastWaits.push(e => { if (e === undefined) f(); else r(e); }); }); } async allSettled() { if (this.running === 0) { if (this.errors.length === 0) return; throw new YBatchErrors(this.errors); } return new Promise(f => { this.allSettledWaits.push(f); }).then(errors => { if (errors.length === 0) return; throw new YBatchErrors(errors); }); } } exports.YBatch = YBatch; //# sourceMappingURL=y-batch.js.map