RateLimitExecutor
RateLimitExecutor enforces a maximum number of task executions per time window. Tasks that exceed the rate limit are queued and executed when the window allows.
Best for API rate limiting Use
RateLimitExecutorwhen calling APIs with rate limits, such as 100 requests per minute.
Import
Section titled “Import”Root package:
import { RateLimitExecutor } from "@vgerbot/async";Module subpath:
import { RateLimitExecutor } from "@vgerbot/async/executors";Leaf subpath:
import { RateLimitExecutor } from "@vgerbot/async/executors/RateLimitExecutor";Quick example
Section titled “Quick example”import { RateLimitExecutor } from "@vgerbot/async";
// Max 5 requests per secondconst executor = new RateLimitExecutor({ maxRequests: 5, windowMs: 1000,});
for (let i = 0; i < 20; i++) { executor.exec(async (token) => { return fetch(`/api/data?page=${i}`); });}
// Requests are throttled to 5 per secondWhen to use RateLimitExecutor
Section titled “When to use RateLimitExecutor”- API rate limits: Respect rate limits of external APIs.
- Resource throttling: Limit the rate of resource-intensive operations.
- Compliance: Ensure operations stay within contractual rate limits.
- Gentle polling: Space out requests to avoid overwhelming a server.
class RateLimitExecutor extends BaseTaskExecutor { constructor(options: RateLimitOptions);
exec<T>(task: AsyncTask<T>, options?: TaskOptions): TaskHandle<T>; cancel(reason?: unknown): void; cancel(options: TaskCancelOptions): void; shutdown(reason?: unknown): void; isCancelled(): boolean;}Constructor
Section titled “Constructor”new RateLimitExecutor(options: RateLimitOptions)RateLimitOptions
Section titled “RateLimitOptions”| Option | Type | Default | Description |
|---|---|---|---|
maxRequests |
number |
— | Maximum number of requests allowed per time window. |
windowMs |
number |
— | Time window in milliseconds. |
Methods
Section titled “Methods”exec(task, options?)
Section titled “exec(task, options?)”Submits a task for execution. If the rate limit has been reached, the task is queued until the sliding window allows it.
| Parameter | Type | Default | Description |
|---|---|---|---|
task |
AsyncTask<T> |
— | Async function that receives a CancellableToken. |
options |
TaskOptions |
undefined |
Task metadata (kind, name, metadata). |
cancel(reason?) / cancel(options)
Section titled “cancel(reason?) / cancel(options)”Cancels matching tasks. Use shutdown() to permanently disable the executor.
Execution model
Section titled “Execution model”RateLimitExecutor uses a sliding window algorithm. It tracks the timestamps of recent executions within the window. When a new task is submitted:
- If the number of executions in the current window is below
maxRequests, the task starts immediately. - If the limit is reached, the task is queued and waits until enough timestamps expire from the window.
- Queued tasks are started in FIFO order as the window slides forward.
// 3 requests per secondconst executor = new RateLimitExecutor({ maxRequests: 3, windowMs: 1000,});
// First 3 start immediately// 4th and 5th wait until the window slidesfor (let i = 0; i < 5; i++) { executor.exec(async () => `request-${i}`);}Error handling
Section titled “Error handling”If a task throws, the task’s promise rejects with that error. The executor continues processing subsequent tasks.
Cancellation
Section titled “Cancellation”Executor-level cancellation
Section titled “Executor-level cancellation”Calling cancel() cancels pending/running tasks. Use shutdown() to permanently disable the executor.
const executor = new RateLimitExecutor({ maxRequests: 10, windowMs: 1000 });
executor.exec(async () => "task1");executor.exec(async () => "task2");
executor.cancel("Shutting down");Selective cancellation by kind
Section titled “Selective cancellation by kind”executor.exec(async () => "important", { kind: "critical" });executor.exec(async () => "background", { kind: "batch" });
executor.cancel({ kind: "batch" });TypeScript tips
Section titled “TypeScript tips”exec is generic over T.
const result = await executor.exec(async (token) => { const res = await token.wrap(fetch("/api/data")); return res.json() as Promise<{ items: string[] }>;});Related APIs
Section titled “Related APIs”ThrottleTaskExecutor— guarantees at most one execution per wait period.DebounceTaskExecutor— delays execution until calls stop.PoolTaskExecutor— concurrency-limited pool.throttle— function-level throttle.debounce— function-level debounce.