unqommented
Version:
A Node.js utility that quickly identifies files with uncommented code in your codebase. Designed for developers who want to efficiently tell LLMs exactly which files need comments added.
67 lines (59 loc) • 2.46 kB
JavaScript
/**
* @file Concurrency management utilities
* @description Provides functions for managing concurrent async operations
* @module concurrency-utils
*/
const localVars = require('../config/localVars');
/**
* @function createLimiter
* @description Creates a concurrency limiter to manage the number of parallel async tasks.
* @rationale This in-house limiter was implemented to avoid introducing ESM-only dependencies
* like 'p-limit', ensuring the library remains fully CommonJS compatible. This is a strategic
* choice to maintain broader compatibility and a smaller dependency tree.
* @scalability By controlling the number of concurrent file operations, this function is critical
* for preventing resource exhaustion (e.g., file handle limits) when scanning a large number of
* files. The `CONCURRENCY_LIMIT` offers a trade-off between execution speed and system stability.
* @param {number} max - The maximum number of concurrent tasks allowed.
* @returns {Function} A function that takes an async function as input and returns a new
* function that respects the concurrency limit.
*/
function createLimiter(max) {
// Enforce that the limit is a positive integer, preventing invalid states.
if (!Number.isInteger(max) || max <= 0) {
throw new Error(localVars.ERROR_MESSAGES.LIMIT_NOT_POSITIVE_INT);
}
const queue = []; // Stores pending tasks
let activeCount = 0; // Tracks the number of currently running tasks
// The next function is the core of the limiter. It checks if a new task can be started
// and, if so, dequeues and executes it.
const next = () => {
// Do not start a new task if the limit is reached or the queue is empty.
if (activeCount >= max || queue.length === 0) return;
const { fn, resolve, reject } = queue.shift();
activeCount += 1;
// Execute the task and handle its completion, ensuring the next task is triggered.
Promise.resolve()
.then(fn)
.then(result => {
activeCount -= 1;
resolve(result);
next();
})
.catch(error => {
activeCount -= 1;
reject(error);
next();
});
};
// The returned function wraps the user's async function in a Promise, adding it to the
// queue and starting the execution loop.
return fn => {
return new Promise((resolve, reject) => {
queue.push({ fn, resolve, reject });
next();
});
};
}
module.exports = {
createLimiter,
};