UNPKG

signalk-parquet

Version:

Vessel data Parquet file archive with automated value and geospatial triggers. History API compliant with cloud backups and queries.

66 lines 1.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConcurrencyLimiter = void 0; /** * Limits the number of concurrent promise executions * * @example * const limiter = new ConcurrencyLimiter(5); * const results = await limiter.map(items, async (item) => { * return await processItem(item); * }); */ class ConcurrencyLimiter { constructor(maxConcurrent = 10) { this.running = 0; this.queue = []; if (maxConcurrent <= 0) { throw new Error('maxConcurrent must be positive'); } this.maxConcurrent = maxConcurrent; } /** * Execute an async function with concurrency limiting */ async execute(fn) { // Wait if at capacity while (this.running >= this.maxConcurrent) { await new Promise(resolve => this.queue.push(resolve)); } this.running++; try { return await fn(); } finally { this.running--; // Resume next queued operation const next = this.queue.shift(); if (next) { next(); } } } /** * Map over an array with concurrency limiting * Similar to Promise.all() but with controlled concurrency * * @param items - Array of items to process * @param fn - Async function to execute for each item * @returns Array of results in the same order as input */ async map(items, fn) { return Promise.all(items.map((item, index) => this.execute(() => fn(item, index)))); } /** * Get current concurrency statistics */ getStats() { return { running: this.running, queued: this.queue.length, maxConcurrent: this.maxConcurrent, }; } } exports.ConcurrencyLimiter = ConcurrencyLimiter; //# sourceMappingURL=concurrency-limiter.js.map