A promise pool with RPS limiter.
Find a file
Anton Nesterov 9ca50199f9 [ci] jsr job
2024-07-11 01:28:14 +02:00
.github/workflows [ci] jsr job 2024-07-11 01:28:14 +02:00
dist add jsr 2024-07-11 01:20:10 +02:00
.gitignore init 2024-07-11 01:14:10 +02:00
bun.lockb init 2024-07-11 01:14:10 +02:00
jsr.json add jsr 2024-07-11 01:20:10 +02:00
limiter.test.ts init 2024-07-11 01:14:10 +02:00
limiter.ts add jsr 2024-07-11 01:20:10 +02:00
package.json add jsr 2024-07-11 01:20:10 +02:00
README.md add jsr 2024-07-11 01:20:10 +02:00
tsconfig.json init 2024-07-11 01:14:10 +02:00

Limiter

A promise pool with RPS limiter.

Features:

  • TypeScript first
  • Limits parrallel promises execution
  • Limits RPS (requests per second), evenly distributes the requests over time
  • Able to retry
  • Simple API
  • Simple async/await flow
  • Allows to handle errors silently using onError callback
  • Works with any runtime (Bun/Deno/Node)

Install

bun add github:nesterow/limiter # or pnpm

Usage

Limit number of requests

import { Limiter } from "@nesterow/limiter";

const task = () => {
  await fetch("https://my.api.xyz");
  // ... write
};

const limiter = new Limiter({
  limit: 10,
});

for (let i = 0; i < 100; i++) {
  await limiter.process(task);
}

Limit RPS

import {Limiter} from '@nesterow/limiter'

const execEvery100ms = () => {
    await fetch('https://my.api.xyz')
    // ... write
}

const limiter = new Limiter({
    limit: 20
    rps: 10
})

for (let i=0; i < 100; i++) {
    await limiter.process(execEvery100ms)
}

Retry

import {Limiter, LimiterRetryError} from '@nesterow/limiter'

const retry5times = () => {
    await fetch('https://my.api.xyz')
    throw new Error("Connection refused")
    // ... write
}

const limiter = new Limiter({
    limit: 20
    maxRetry: 5
})

for (let i=0; i < 100; i++) {
    try {
        await limiter.process(retry5times)
    } catch(e) {
        if (e instanceof LimiterRetryError) {
            // Logger.log(e)
        }
    }
}

Handle errors in background

import {Limiter, LimiterRetryError} from '@nesterow/limiter'

const wontStopPooling = () => {
    await fetch('https://my.api.xyz')
    throw new Error("Connection refused")
    // ... write
}

const limiter = new Limiter({
    limit: 20
    maxRetry: 5,
    onError(error) {
        // Logger.error(error)
    }
})

for (let i=0; i < 100; i++) {
    await limiter.process(wontStopPooling)
}