/**
* Throttles requests for user records to prevent overwhelming the API,
* especially in non-production environments.
*
* @param {function} fetchUser - The function that fetches user records. Expected to return a Promise.
* @param {number} maxRequestsPerMinute - The maximum number of requests allowed per minute.
* @returns {function} - A throttled version of the fetchUser function.
*/
function throttleUserRequests(fetchUser, maxRequestsPerMinute) {
let requestQueue = []; // Queue to hold pending requests
let lastExecutionTime = 0; // Timestamp of the last successful execution
let running = false; // Flag to indicate if throttling is currently active
/**
* Executes a request if allowed by the throttling limits.
*/
async function executeRequest() {
if (running) return; // Prevent concurrent executions
if (requestQueue.length === 0) {
return; // No requests in the queue
}
const now = Date.now();
const timeSinceLastExecution = now - lastExecutionTime;
if (timeSinceLastExecution < 60000 / maxRequestsPerMinute) { // Check if enough time has passed
// Not enough time has passed, push the request back to the queue
requestQueue.push(requestQueue.shift()); // Move the request to the end
return;
}
running = true; // Mark throttling as running
const request = requestQueue.shift(); // Get the next request from the queue
try {
const result = await fetchUser(request.params); // Execute the request
lastExecutionTime = Date.now(); // Update the last execution time
} catch (error) {
console.error("Error fetching user:", error);
// Handle the error appropriately (e.g., retry, log, alert)
} finally {
running = false; // Mark throttling as done
executeRequest(); // Schedule the next request
}
}
/**
* Wraps the original fetchUser function to apply throttling.
* @param {object} params - Parameters to pass to fetchUser.
* @returns {Promise} - A promise that resolves with the result of the fetchUser call.
*/
return async function (...params) {
return new Promise((resolve, reject) => {
requestQueue.push({ params, resolve, reject }); // Add request to the queue
executeRequest(); // Start the throttling process
});
};
}
Add your comment