1. /**
  2. * Throttles requests for user records to prevent overwhelming the API,
  3. * especially in non-production environments.
  4. *
  5. * @param {function} fetchUser - The function that fetches user records. Expected to return a Promise.
  6. * @param {number} maxRequestsPerMinute - The maximum number of requests allowed per minute.
  7. * @returns {function} - A throttled version of the fetchUser function.
  8. */
  9. function throttleUserRequests(fetchUser, maxRequestsPerMinute) {
  10. let requestQueue = []; // Queue to hold pending requests
  11. let lastExecutionTime = 0; // Timestamp of the last successful execution
  12. let running = false; // Flag to indicate if throttling is currently active
  13. /**
  14. * Executes a request if allowed by the throttling limits.
  15. */
  16. async function executeRequest() {
  17. if (running) return; // Prevent concurrent executions
  18. if (requestQueue.length === 0) {
  19. return; // No requests in the queue
  20. }
  21. const now = Date.now();
  22. const timeSinceLastExecution = now - lastExecutionTime;
  23. if (timeSinceLastExecution < 60000 / maxRequestsPerMinute) { // Check if enough time has passed
  24. // Not enough time has passed, push the request back to the queue
  25. requestQueue.push(requestQueue.shift()); // Move the request to the end
  26. return;
  27. }
  28. running = true; // Mark throttling as running
  29. const request = requestQueue.shift(); // Get the next request from the queue
  30. try {
  31. const result = await fetchUser(request.params); // Execute the request
  32. lastExecutionTime = Date.now(); // Update the last execution time
  33. } catch (error) {
  34. console.error("Error fetching user:", error);
  35. // Handle the error appropriately (e.g., retry, log, alert)
  36. } finally {
  37. running = false; // Mark throttling as done
  38. executeRequest(); // Schedule the next request
  39. }
  40. }
  41. /**
  42. * Wraps the original fetchUser function to apply throttling.
  43. * @param {object} params - Parameters to pass to fetchUser.
  44. * @returns {Promise} - A promise that resolves with the result of the fetchUser call.
  45. */
  46. return async function (...params) {
  47. return new Promise((resolve, reject) => {
  48. requestQueue.push({ params, resolve, reject }); // Add request to the queue
  49. executeRequest(); // Start the throttling process
  50. });
  51. };
  52. }

Add your comment