https://github.com/articulate/speedtrap
https://github.com/articulate/speedtrap
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/articulate/speedtrap
- Owner: articulate
- Created: 2020-07-24T20:35:33.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2023-09-27T14:00:39.000Z (almost 3 years ago)
- Last Synced: 2025-08-24T10:59:43.803Z (11 months ago)
- Language: JavaScript
- Homepage:
- Size: 74.2 KB
- Stars: 0
- Watchers: 52
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# :police_car: SpeedTrap
Tired of blowing 3rd party API rate limits? Does your 3rd party API keep counting requests even when it returns a 429? Does your app run in a distributed environment? Does your app have a "heavy foot"?? Then this library is for you! SpeedTrap is a tool that uses redis to keep track of your speed. Just `run()` the SpeedTrap with your function and parameters, and get a `Promise` back with your result. But watch your speed! If you go too fast, the SpeedTrap Will catch you and ticket you with a rejected `Promise`. You wont be running anywhere.
## Config options
| Name | Type | Description | Default |
| ---- | ------ | ----------- | ------- |
| duration | Integer | the duration of the sliding window for speed calculation | |
| letOffWithAWarning | Boolean | when `true` will allow your function to still run when the speed limit is exceeded | false |
| name | String | the unique name of your SpeedTrap used to create redis keys | |
| onExceeded | Function | an optional function that will be called when the speed limit is exceeded | noop |
| max | Integer | the number off allowed calls per sliding duration window | |
| redis | [redis client](https://www.npmjs.com/package/ioredis) | the redis client to be used for tracking the rate | |
## Usage
Create the SpeedTrap with your options object. Then when you are ready, call `speedTrap.run()` with your function and parameters
```js
const { SpeedTrap } = require('@articulate/speedtrap')
const RedisClient = require('ioredis')
const redisClient = new RedisClient('my-redis-url')
function onRateLimitExceeded(info) {
const {
waitTime // The time (ms) until a run can be made again
} = info
console.info(`Speed limit exceeded, must wait at least ${waitTime}ms`)
}
const config = {
name: 'my-speed-trap',
duration: 2000,
max: 200,
onExceeded: onRateLimitExceeded,
redis: redisClient,
}
const speedTrap = new SpeedTrap(config)
function makeApiCall(param1, param2) {
return /* a call to a crummy rate limited 3rd party marketing api */
}
speedTrap.run(myApiCall, param1, param2)
.then(doOtherThings)
.catch((error) => {
if (error.isSpeedTrap) {
// We were going too fast!! API call was not made. Maybe we sleep and retry?
console.log(`got ticketed, gonna have to wait ${error.waitTime}ms`)
} else {
throw error // not from speeding...
}
})
```
## Let off with a warning
Want to be let off with a warning? Better hope you get a nice officer. The `letOffWithAWarning` configuration option will allow your function to continue running, but rest assured a warning will still be issued to the handler you provided for the `onExceeded` option.
## Contributing
If you have Docker Compose installed, you can run lint and tests with:
```bash
docker compose run --rm test
```
Run tests in watch mode with:
```bash
docker compose run --rm test yarn test --watchAll
```
You can also run without Docker Compose by setting a `REDIS_URL` environment variable.
```bash
REDIS_URL=redis://localhost:6379 yarn test
```