limiter/README.md

124 lines
2.2 KiB
Markdown
Raw Permalink Normal View History

2024-07-10 23:14:10 +00:00
# Limiter
2024-07-10 23:14:38 +00:00
A promise pool with RPS limiter.
2024-07-10 23:14:10 +00:00
Features:
- [x] TypeScript first
- [x] Limits parrallel promises execution
- [x] Limits RPS (requests per second), evenly distributes the requests over time
- [x] Able to retry
- [x] Simple API
- [x] Simple async/await flow
- [x] Allows to handle errors silently using onError callback
- [x] Works with any runtime (Bun/Deno/Node)
## Install
```bash
bun add github:nesterow/limiter # or pnpm
```
2024-07-11 15:09:29 +00:00
## API
- limit - default 10
- maxRetry - number of retries, use Infinity to retry until dead
- rps - if set throttles task execution based on provided rate per second
- onError() - if set, the errors are handled silently
```typescript
limiter = new Limiter({
limit?: number;
maxRetry?: number;
rps?: number;
onError?: (error: Error) => Promise<void> | void;
})
```
2024-07-10 23:14:10 +00:00
## Usage
2024-07-10 23:36:44 +00:00
### Add tasks
```typescript
2024-07-11 15:09:29 +00:00
import { Limiter } from "@nesterow/limiter";
2024-07-10 23:36:44 +00:00
const limiter = new Limiter({
limit: 20,
});
2024-07-11 15:09:29 +00:00
const task = () => {
await fetch(url);
};
2024-07-10 23:36:44 +00:00
limiter.process(task);
limiter.process(task);
limiter.process(task);
2024-07-11 15:09:29 +00:00
2024-07-11 15:10:16 +00:00
await limiter.done();
2024-07-10 23:36:44 +00:00
```
2024-07-11 15:09:29 +00:00
### Batch processing
2024-07-10 23:14:10 +00:00
```typescript
2024-07-10 23:20:10 +00:00
import { Limiter } from "@nesterow/limiter";
2024-07-10 23:14:10 +00:00
const task = () => {
2024-07-10 23:20:10 +00:00
await fetch("https://my.api.xyz");
};
2024-07-10 23:14:10 +00:00
const limiter = new Limiter({
2024-07-10 23:20:10 +00:00
limit: 10,
});
2024-07-10 23:14:10 +00:00
2024-07-11 15:09:29 +00:00
// process 100 tasks, 10 at the same time
2024-07-10 23:36:44 +00:00
await limiter.process(...Array.from({ length: 100 }, () => task()));
2024-07-10 23:14:10 +00:00
```
### Limit RPS
```typescript
2024-07-10 23:36:44 +00:00
import { Limiter } from "@nesterow/limiter";
2024-07-10 23:14:10 +00:00
const execEvery100ms = () => {
2024-07-10 23:36:44 +00:00
await fetch("https://my.api.xyz");
};
2024-07-10 23:14:10 +00:00
const limiter = new Limiter({
2024-07-10 23:36:44 +00:00
limit: 20,
rps: 10,
});
2024-07-10 23:14:10 +00:00
2024-07-11 15:09:29 +00:00
// trottle every 100ms
2024-07-10 23:36:44 +00:00
await limiter.process(...Array.from({ length: 100 }, () => execEvery100ms()));
2024-07-10 23:14:10 +00:00
```
### Retry
```typescript
2024-07-10 23:36:44 +00:00
import { Limiter, LimiterRetryError } from "@nesterow/limiter";
2024-07-10 23:14:10 +00:00
const retry5times = () => {
2024-07-10 23:36:44 +00:00
await fetch("https://my.api.xyz");
throw new Error("Connection refused");
};
2024-07-10 23:14:10 +00:00
const limiter = new Limiter({
2024-07-10 23:36:44 +00:00
limit: 20,
maxRetry: 5,
});
for (let i = 0; i < 100; i++) {
try {
2024-07-11 15:09:29 +00:00
await limiter.process(...Array.from({ length: 100 }, () => retry5times()));
2024-07-10 23:36:44 +00:00
} catch (e) {
if (e instanceof LimiterRetryError) {
// Logger.log(e)
2024-07-10 23:14:10 +00:00
}
2024-07-10 23:36:44 +00:00
}
2024-07-10 23:14:10 +00:00
}
```
2024-07-11 15:09:29 +00:00
## License
2024-07-10 23:14:10 +00:00
2024-07-11 15:09:29 +00:00
MIT