Socket
Socket
Sign inDemoInstall

leaky-bucket

Package Overview
Dependencies
0
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.1 to 4.1.0

2

package.json
{
"name": "leaky-bucket",
"description": "A fast and efficient leaky bucket implementation",
"version": "4.0.1",
"version": "4.1.0",
"homepage": "https://github.com/linaGirl/leaky-bucket",

@@ -6,0 +6,0 @@ "author": "Lina van der Weg <lina@vanderweg.ch> (http://vanderweg.ch/)",

@@ -5,10 +5,15 @@ # leaky-bucket

Leaky buckets are often used to rate limits calls to APIs. They can be used on the server, to make sure
the client does not send too many requests and on the client, to make sure to not to send too many
requests to a server rate limiting using a leaky bucket. Leaky buckets are burstable: if a server lets a
client send 10 requests per minute, it normally lets the user burst those 10 reuests. after that only one
request per 6 seconds may be sent (60 seconds / 10 requests). If the user stops sending requests, the bucket
is filled up again so that the user may send a burst of requests again.
Leaky buckets are often used to rate limits calls to APIs. They can be
used on the server, to make sure the client does not send too many
requests in a short time or on the client, to make sure to not to send
too many requests to a server, that is rate limiting using a leaky
bucket.
Leaky buckets are burstable: if a server lets a client send 10 requests
per minute, it normally lets the user burst those 10 requests in a short
time. After that only one request every 6 seconds may be sent (60 seconds
/ 10 requests). If the user stops sending requests, the bucket is filled
up again so that the user may send a burst of requests again.
New in Version 4:

@@ -21,2 +26,4 @@ - dropped node.js support for node <12 (es modules)

- added the canExecuteNow method
- added the getCapacity method
- added the getCurrentCapacity method

@@ -33,13 +40,2 @@

Sets up the leaky bucket. Accpets three optional options
- capacity: this is the amount of items that may be processed per interval, if the items cost is 1 (which is the default)
- interval: this is the interval, in which the capacity may be used
- timeout: defines, how long it takes until items are rejected due to an overflow. defaults to the value of the interval, so that the overflow occurs at the same time the bucket is empty.
- debug: print log messages using console.log
- initialCapacity: the bucket starts normally with the full capacity, this lets you override this with a custom value
- idleTimeout: if set, the bucket will emit the idleTimeout event after the specified amount of milliseconds as soon the bucket is empty and at full capacity
```javascript

@@ -55,21 +51,68 @@ import LeakyBucket from 'leaky-bucket';

#### option: capacity
### throttle()
The capacity defines how many requests may be sent oer interval. If the
capacity is 100 and the interval is 60 seconds and a request has a cost
of 1, every 60 seconds 1000 request may be processed. If the request
cost is 4, jsut 25 requests may be processed every 60 seconds.
The throttle method is used to delay items until the bucket leaks them, thus rate limiting them. If the bucket is overflowing, which is when items cannot be executed within the timeout, the throttle method will reject using an error.
The complete capacity can be used in a burst. This means for the example
above, 100 requests can be processed immediately. Thereafter every request
has to weit for 0.6 seconds (60 seconds / 100 capacity) if the request
cost is 1.
This method accepts two optional paramters:
#### option: interval
- cost: the cost of the item, defaults to 1
- append: if the ittem should be appended or added at the first position in the queue, defaults to true
The interval defines, how much seconds it takes to refill the bucket to
its full capacity. The bucket is not filled every interval, but continously.
#### option timeout
Normally, the bucket will throw errors when the throttle() method is called
when the bucket is empty. When a timeout is defined, the bucket will queue
items as long they can be executed within the timeout. Defaults to 0, which
will not queue any items if the bucket is empty.
#### option initialCapacity
Some rate limited services will start out with an empty bucket, or refill
the bucket not continusly but in an interval. This option can be used to
set a starting capacity beween 0 and the configured capacity. If set to 0
and a request shall be processed immediately and the timeout is 0, the
bucket will reject the request.
#### idleTimeout
If this option is set, the bucket will emti a idleTimeout event after the
bucket is filled completely and no requests are waiting. Configured in
milliseconds.
#### debug
If set to true, the bucket will print debug logs using console.log()
### async bucket.throttle(cost = 1)
This is the main method used for procsessing requests. If this method is
called and the bucket has more capacity left that the request costs, it
will continue. If the capacity is less than the cost, it will throw an
error. If the timeout option is configured, the method will sleep until
there is enough capacity to process it.
This method accepts two optional parameters:
- cost: the cost of the item, defaults to 1.
- append: if set to false, the item is added at the beginning of the queue and will thus executed before all other queued items. Defaults to true;
```javascript
/// throttle an individual item
// throttle an individual item
await bucket.throttle();
doThings();
// Throttle aset of items, waiting for each one to complete, before it's added to the bucket
// Throttle a set of items, waiting for each one to complete before the next one is executed
for (const item of set.values()) {
await bucket.throttle();
doThings();

@@ -79,6 +122,5 @@ }

// throttle items, add them to the bucket in paralle
// throttle multiple items and wait untiul all are finished
await Promise.all(Array.from(set).map(async(item) => {
await bucket.throttle();
doThings();

@@ -89,9 +131,10 @@ }));

### pause()
### pause(seconds)
The pause method can be use to pause the bucket for n seconds until it is allwed to resume.
The pause method can be use to pause the bucket for n seconds. Same as the throttle call but does not throw errors when the bucket is over its capacity.
```javascript
bucket.pause();
bucket.pause(2);

@@ -101,5 +144,16 @@ ````

### pauseByCost(cost)
The pause method can be use to pause the bucket for a specific cost. Same as the throttle call but does not throw errors when the bucket is over its capacity.
```javascript
bucket.pauseByCost(300);
````
### pay(cost)
removes the defined cost from the bucket
Removes the defined cost from the bucket without taking any action. Reduces the current capacity.

@@ -115,3 +169,3 @@

shuts down the bucket. Removes all pending items wihtout executing them. The bucket cannot be reused thereafter!
Shuts down the bucket, clears all timers. Removes all pending items wihtout executing them. The bucket cannot be reused thereafter!

@@ -124,6 +178,54 @@

### getCapacity()
Returns the total capacity of the bucket.
```javascript
const capacity = bucket.getCapacity();
````
### getCurrentCapacity()
Returns the current capacity of the bucket.
```javascript
const currentCapacity = bucket.getCurrentCapacity();
````
### setTimeout(seconds)
Sets the amount of seconds the bucket queue items before it starts to reject them. Same as the timeout option in the constructor
```javascript
bucket.setTimeout(300);
````
### setInterval(seconds)
Sets the interval it takes to refill the bucket completely. Same as the interval option in the constructor
```javascript
bucket.setInterval(60);
````
### setCapacity(capacity)
Sets the capacity of the bucket. Same as the capacity option in the constructor
```javascript
bucket.setTimeout(1000);
````
### event 'idleTimeout'
Is emitted, if the bucket is at full capacity and idle for N milliseconds
This event is emitted, if the bucket is at full capacity and idle for N milliseconds
```javascript

@@ -146,3 +248,24 @@ const bucket = new Bucket({

### event 'idle'
This event is emitted, when the bucket is idle, thus no items are waiting to be executed.
```javascript
const bucket = new Bucket({
capacity: 60,
interval: 60,
idleTimeout: 2000,
});
bucket.on('idle', (bucketInstance) => {
console.log('bucket is idling');
});
// you may remove the listener if you want
bucket.off('idle');
````
## Browser

@@ -175,6 +298,8 @@

const app = express()
const buckets = new Map();
const costOfOperation = 50;
app.use((req, res, next) => {
// your cookie should be secure and not guessable by the user
const userUid = req.cookies.userUid;

@@ -185,3 +310,3 @@

const bucket = new Bucket({
capacity: 60,
capacity: 1000,
interval: 60,

@@ -191,3 +316,3 @@ idleTimeout: 120 * 1000 // 120 seconds

// end the bucket, remove it from memory
// end the bucket, remove it from memory when it becomes idle
bucket.on('idleTimeout', () => {

@@ -198,3 +323,3 @@ bucket.end();

// store for later use
// store for later access
buckets.set(userUid, bucket);

@@ -218,6 +343,10 @@ }

// all set and fine, continue to process the request
res.set('x-request-cost', costOfOperation);
res.set('x-rate-limit', `${bucket.currentCapacity}/${bucket.capacity}`);
res.set('x-rate-limit-cost', costOfOperation);
res.set('x-rate-limit-bucket-size', bucket.getCapacity());
res.set('x-rate-limit-remaining-size', bucket.getCurrentCapacity());
next();
});
app.listen(8080);
````

@@ -133,4 +133,23 @@ import EventEmitter from './EventEmitter.js';

/**
* returns the capacity
*
* @return {number} The capacity.
*/
getCapacity() {
return this.capacity;
}
/**
* returns the current capacity
*
* @return {number} The current capacity.
*/
getCurrentCapacity() {
return this.currentCapacity;
}
/**
* either executes directly when enough capacity is present or delays the

@@ -190,4 +209,8 @@ * execution until enough capacity is available.

if (this.queue.length === 0 && this.emptyPromiseResolver) {
this.emptyPromiseResolver();
if (this.queue.length === 0) {
if (this.emptyPromiseResolver) {
this.emptyPromiseResolver();
}
this.emit('idle', this);
}

@@ -198,10 +221,2 @@ }

/**
* Determines ability to execute an item now.
*
* @param {number} cost The cost
*/
canExecuteNow(cost) {
this.currentCapacity >= cost;
}

@@ -213,2 +228,4 @@

* that is emitted
*
* @private
*/

@@ -340,2 +357,4 @@ async isEmpty() {

* it shoudl reach ful capacity. used for the idle event
*
* @private
*/

@@ -358,2 +377,4 @@ startRefillTimer() {

* Stops the refill timer.
*
* @private
*/

@@ -370,2 +391,4 @@ stopRefillTimer() {

* Stops the idle timer.
*
* @private
*/

@@ -382,2 +405,4 @@ stopIdleTimer() {

* at full capacity
*
* @private
*/

@@ -461,3 +486,3 @@ startIdleTimer() {

/**
* pasue the bucket for the given cost. means that an item is added in the
* pause the bucket for the given cost. means that an item is added in the
* front of the queue with the cost passed to this method

@@ -464,0 +489,0 @@ *

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc