TS Leaky Bucket
Port of leaky-bucket to Typescript. Original package was using experimental modules which required a runtime flag and also didn't have nice Typescript types.
Overview
Implementation of a leaky bucket algorithm to support throttling / rate limiting. Check out ts-request-rate-limiter if you are looking for a library to limit client requests (e.g. rate limiting requests to an API).
Install
npm i ts-leaky-bucket
Usage
LeakyBucket
Create a Constructor Options
capacity
- unit of capacity of a bucketintervalMillis
- time to fully drain the buckettimeoutMillis
- time to queue additional items over capacity
; // constructor takes `LeakyBucketOptions`; // OR just use constructor directly // constructor with options;
Throttling
Way to add things to a bucket and then wait for the bucket to leak them.
maybeThrottle(cost: number = 1, append: boolean = true, isPause: boolean = false): Promise<void>
cost
- how much unit capacity to take for thismaybeThrottle
append
- add to back of queue or beginningisPause
- used to denote an item being a pause request
; ; async myBizLogicToThrottle: void
Pausing
Two ways to pause the bucket from leaking:
pause(millis = 1000)
- pause the bucket from leaking for givenmillis
pauseByCost(cost: number)
- pauses the bucket from leaking for a given forcost
// create bucket... // do throttled work... // pause leaking for a secondawait bucket.pause; // pause for 100 units of costawait bucket.pauseForCost100; // do more thottled work
Await Empty
If you want to wait for all items to leak out of a bucket you can use awaitEmpty
.
// create bucket... // do throttled work... // wait for bucket to emptyawait bucket.awaitEmpty;
Other Methods
pay(cost: number)
- post-hoc leak after a throttle to pay down additional unit coststopTimerAndClearQueue
- clear the timer and queue
Development Commands
npm i
- install depsnpm run test
- run testsnpm run publish
- publish
Changes
I've changed the code a bit from the original:
- Naming changes
isEmpty
=>awaitEmpty
to capture that a call to this waits until the queue emptiesthrottle
=>maybeThrottle
to capture that it may return immediately if there is capacity or wait if notinterval
=>intervalMillis
clarify unit of timetimeout
=>additionalTimeoutMillis
clarify unit of time and also make clear this is in addition tointervalMillis
requestRate
=>requestRateInSecs
clarify unit of time
- API Changes
- Uses milliseconds as the time unit instead of a mix between seconds and milliseconds
- Does not allow post creation options changing; Original allows updating
capacity
,interval
,timeout
at runtime which I didn't want to encourage additionalTimeoutMillis
is added tointervalMillis
instead of treated as a independent variablepause(millis: number)
uses milliseconds instead of seconds to be consistent- uses
get
ters instead ofgetXXX
for reading options back out