New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

rolling-rate-limiter

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rolling-rate-limiter - npm Package Compare versions

Comparing version 0.1.6 to 0.1.7

.eslintrc.js

22

index.js

@@ -6,6 +6,6 @@ var assert = require("assert");

var redis = options.redis,
interval = options.interval * 1000, // in microseconds
maxInInterval = options.maxInInterval,
minDifference = options.minDifference ? 1000 * options.minDifference : null, // also in microseconds
namespace = options.namespace || (options.redis && ("rate-limiter-" + Math.random().toString(36).slice(2))) || null;
interval = options.interval * 1000, // in microseconds
maxInInterval = options.maxInInterval,
minDifference = options.minDifference ? 1000 * options.minDifference : null, // also in microseconds
namespace = options.namespace || (options.redis && (`rate-limiter-${ Math.random().toString(36).slice(2)}`)) || null;

@@ -37,3 +37,3 @@ assert(interval > 0, "Must pass a positive integer for `options.interval`");

return function (id, cb) {
return function(id, cb) {
if (!cb) {

@@ -56,3 +56,3 @@ cb = id;

batch.expire(key, Math.ceil(interval / 1000000)); // convert to seconds, as used by redis ttl.
batch.exec(function (err, resultArr) {
batch.exec(function(err, resultArr) {
if (err) return cb(err);

@@ -63,3 +63,3 @@

var tooManyInInterval = userSet.length >= maxInInterval;
var timeSinceLastRequest = minDifference && (now - userSet[userSet.length - 1]);
var timeSinceLastRequest = now - userSet[userSet.length - 1];

@@ -70,3 +70,3 @@ var result;

if (tooManyInInterval || timeSinceLastRequest < minDifference) {
result = Math.min(userSet[0] - now + interval, minDifference ? minDifference - timeSinceLastRequest : Infinity);
result = Math.max(tooManyInInterval ? userSet[userSet.length - maxInInterval] - now + interval : 0, minDifference ? minDifference : 0);
result = Math.floor(result / 1000); // convert to miliseconds for user readability.

@@ -81,3 +81,3 @@ } else {

} else {
return function () {
return function() {
var args = Array.prototype.slice.call(arguments);

@@ -104,3 +104,3 @@ var cb = args.pop();

var tooManyInInterval = userSet.length >= maxInInterval;
var timeSinceLastRequest = minDifference && (now - userSet[userSet.length - 1]);
var timeSinceLastRequest = now - userSet[userSet.length - 1];

@@ -111,3 +111,3 @@ var result;

if (tooManyInInterval || timeSinceLastRequest < minDifference) {
result = Math.min(userSet[0] - now + interval, minDifference ? minDifference - timeSinceLastRequest : Infinity);
result = Math.max(tooManyInInterval ? userSet[userSet.length - maxInInterval] - now + interval : 0, minDifference ? minDifference : 0);
result = Math.floor(result / 1000); // convert from microseconds for user readability.

@@ -114,0 +114,0 @@ } else {

{
"name": "rolling-rate-limiter",
"version": "0.1.6",
"version": "0.1.7",
"description": "Rate limiter that supports a rolling window, either in-memory or backed by redis",

@@ -31,7 +31,10 @@ "main": "index.js",

"devDependencies": {
"async": "~0.9.0",
"chai": "~1.10.0",
"eslint": "^3.19.0",
"eslint-config-classdojo": "^1.2.6",
"fakeredis": "~0.3.0",
"chai": "~1.10.0",
"async": "~0.9.0",
"lodash": "^4.17.4",
"mocha": "~2.1.0"
}
}

@@ -1,16 +0,16 @@

var expect = require("chai").expect;
var async = require("async");
var redis = require("fakeredis");
const expect = require("chai").expect;
const async = require("async");
const redis = require("fakeredis");
var RateLimiter = require("../");
const RateLimiter = require("../");
var RateLimitedCounter = function(options) {
var rateLimiter = RateLimiter(options);
var counts = {};
const RateLimitedCounter = function(options) {
const rateLimiter = RateLimiter(options);
const counts = {};
return {
increment: function() {
var args = Array.prototype.slice.call(arguments);
var cb = args.pop();
var userId;
increment () {
const args = Array.prototype.slice.call(arguments);
let cb = args.pop();
let userId;
if (typeof cb === "function") {

@@ -23,21 +23,22 @@ userId = args[0] || "";

counts[userId] = counts[userId] || 0;
var limit = userId ? rateLimiter.bind(null, userId) : rateLimiter;
const limit = userId ? rateLimiter.bind(null, userId) : rateLimiter;
if (cb) {
limit(function(err, blocked) {
if (!blocked) {
limit(function(err, timeLeft) {
if (!timeLeft) {
counts[userId]++;
}
cb(err);
cb(err, timeLeft);
});
} else {
var blocked = limit();
if (!blocked) {
const timeLeft = limit();
if (!timeLeft) {
counts[userId]++;
}
return timeLeft;
}
},
getCount: function(userId) {
getCount (userId) {
return counts[userId || ""];
}
},
};

@@ -47,8 +48,8 @@

describe("rateLimiter", function () {
describe("rateLimiter", function() {
describe("options validation", function() {
var options;
let options;
beforeEach(function() {

@@ -59,3 +60,3 @@ options = {

minDifference: 500,
namespace: "MyNamespace"
namespace: "MyNamespace",
};

@@ -97,9 +98,19 @@ });

it("allows requests that don't exceed the maximum over the interval", function() {
const counter = RateLimitedCounter({
interval: 100,
maxInInterval: 30,
});
for (let n = 0; n < 100; n++) {
counter.increment();
}
expect(counter.getCount()).to.equal(30);
});
it("prevents requests that exceed the maximum over the interval", function() {
var counter = RateLimitedCounter({
interval: 300,
maxInInterval: 30
const counter = RateLimitedCounter({
interval: 100,
maxInInterval: 30,
});
for (var n = 0; n < 100; n++) {
for (let n = 0; n < 100; n++) {
counter.increment();

@@ -111,8 +122,7 @@ }

it("keeps seperate counts for multiple users", function() {
var counter = RateLimitedCounter({
interval: 300,
maxInInterval: 30
const counter = RateLimitedCounter({
interval: 100,
maxInInterval: 30,
});
for (var n = 0; n < 300; n++) {
for (let n = 0; n < 300; n++) {
counter.increment(n % 3);

@@ -127,14 +137,14 @@ }

it("allows requests after the interval has passed", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 100,
maxInInterval: 30
maxInInterval: 30,
});
for (var n = 0; n < 300; n++) {
for (let n = 0; n < 300; n++) {
counter.increment(n % 3);
}
setTimeout(function() {
for (var n = 0; n < 300; n++) {
for (let n = 0; n < 300; n++) {
counter.increment(n % 3);
}
}
expect(counter.getCount(0)).to.equal(60);

@@ -148,9 +158,9 @@ expect(counter.getCount(1)).to.equal(60);

it("doesn't allow consecutive requests less than the minDifferent apart", function() {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 1000000,
maxInInterval: 1000,
minDifference: 100
minDifference: 100,
});
for (var n = 0; n < 300; n++) {
for (let n = 0; n < 300; n++) {
counter.increment(n % 3);

@@ -164,10 +174,10 @@ }

it("returns the time after which actions will be allowed", function() {
var limiter1 = RateLimiter({
const limiter1 = RateLimiter({
interval: 10000,
maxInInterval: 2
maxInInterval: 2,
});
var first = limiter1();
var second = limiter1();
var third = limiter1();
let first = limiter1();
let second = limiter1();
const third = limiter1();
expect(first).to.equal(0);

@@ -178,6 +188,6 @@ expect(second).to.equal(0);

var limiter2 = RateLimiter({
const limiter2 = RateLimiter({
interval: 10000,
maxInInterval: 100,
minDifference: 100
minDifference: 100,
});

@@ -197,5 +207,5 @@

it("prevents requests that exceed the maximum over the interval", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 300,
maxInInterval: 30
maxInInterval: 30,
});

@@ -213,5 +223,5 @@

it("keeps seperate counts for multiple users", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 300,
maxInInterval: 30
maxInInterval: 30,
});

@@ -232,5 +242,5 @@

it("allows requests after the interval has passed", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 150,
maxInInterval: 30
maxInInterval: 30,
});

@@ -245,3 +255,3 @@

counter.increment(n % 3, next);
}, function(err, results) {
}, function(err) {
if (err) throw err;

@@ -258,6 +268,6 @@ expect(counter.getCount(0)).to.equal(60);

it("doesn't allow consecutive requests less than the minDifferent apart", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
interval: 1000000,
maxInInterval: 1000,
minDifference: 100
minDifference: 100,
});

@@ -285,7 +295,7 @@

it("prevents requests that exceed the maximum over the interval", function(done) {
var client = redis.createClient();
var counter = RateLimitedCounter({
const client = redis.createClient();
const counter = RateLimitedCounter({
redis: client,
interval: 300,
maxInInterval: 30
maxInInterval: 30,
});

@@ -303,10 +313,10 @@

it("works when redis is in buffer mode", function(done) {
var client = redis.createClient({return_buffers: true});
const client = redis.createClient({return_buffers: true});
// fakeredis seems to hide this option.
client.options = {};
client.options.return_buffers = true;
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
redis: client,
interval: 300,
maxInInterval: 30
maxInInterval: 30,
});

@@ -324,6 +334,6 @@

it("keeps seperate counts for multiple users", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
redis: redis.createClient(),
interval: 300,
maxInInterval: 30
maxInInterval: 30,
});

@@ -344,6 +354,6 @@

it("allows requests after the interval has passed", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
redis: redis.createClient(),
interval: 150,
maxInInterval: 30
maxInInterval: 30,
});

@@ -358,3 +368,3 @@

counter.increment(n % 3, next);
}, function(err, results) {
}, function(err) {
if (err) throw err;

@@ -371,7 +381,7 @@ expect(counter.getCount(0)).to.equal(60);

it("doesn't allow consecutive requests less than the minDifferent apart", function(done) {
var counter = RateLimitedCounter({
const counter = RateLimitedCounter({
redis: redis.createClient(),
interval: 1000000,
maxInInterval: 1000,
minDifference: 100
minDifference: 100,
});

@@ -391,4 +401,4 @@

it("can share a redis between multiple rate limiters in different namespaces", function(done) {
var client = redis.createClient();
var counters = [
const client = redis.createClient();
const counters = [
RateLimitedCounter({

@@ -403,6 +413,6 @@ redis: client,

maxInInterval: 15,
})
}),
];
async.times(200, function(n, next) {
var counter = counters[n % 2];
const counter = counters[n % 2];
counter.increment(n % 3, next);

@@ -422,8 +432,8 @@ }, function(err) {

it("can share a redis between multiple rate limiters in the same namespace", function(done) {
var client = redis.createClient();
var namespace = Math.random().toString(36).slice(2);
var counters = [
const client = redis.createClient();
const namespace = Math.random().toString(36).slice(2);
const counters = [
RateLimitedCounter({
redis: client,
namespace: namespace,
namespace,
interval: 300,

@@ -434,9 +444,9 @@ maxInInterval: 30,

redis: client,
namespace: namespace,
namespace,
interval: 300,
maxInInterval: 30,
})
}),
];
async.times(200, function(n, next) {
var counter = counters[(n + 1) % 2];
const counter = counters[(n + 1) % 2];
counter.increment(n % 3, next);

@@ -447,8 +457,8 @@ }, function(err) {

// CountXY is the count for counter x and user y.
var count00 = counters[0].getCount(0);
var count01 = counters[0].getCount(1);
var count02 = counters[0].getCount(2);
var count10 = counters[1].getCount(0);
var count11 = counters[1].getCount(1);
var count12 = counters[1].getCount(2);
const count00 = counters[0].getCount(0);
const count01 = counters[0].getCount(1);
const count02 = counters[0].getCount(2);
const count10 = counters[1].getCount(0);
const count11 = counters[1].getCount(1);
const count12 = counters[1].getCount(2);

@@ -469,6 +479,6 @@ expect(count00 + count10).to.equal(30);

it("returns the time after which actions will be allowed", function(done) {
var limiter1 = RateLimiter({
const limiter1 = RateLimiter({
redis: redis.createClient(),
interval: 10000,
maxInInterval: 2
maxInInterval: 2,
});

@@ -485,6 +495,6 @@ async.times(3, function(n, next) {

var limiter2 = RateLimiter({
const limiter2 = RateLimiter({
interval: 10000,
maxInInterval: 100,
minDifference: 100
minDifference: 100,
});

@@ -503,12 +513,12 @@ async.times(3, function(n, next) {

it("ttl functions properly", function(done) {
var client = redis.createClient();
var namespace = Math.random().toString(36).slice(2);
var limiter = RateLimiter({
const client = redis.createClient();
const namespace = Math.random().toString(36).slice(2);
const limiter = RateLimiter({
redis: client,
interval: 10000,
maxInInterval: 5,
namespace: namespace
namespace,
});
limiter("1", function(err, result) {
var key = namespace + "1";
limiter("1", function() {
const key = `${namespace }1`;
client.ttl(key, function(err, result) {

@@ -515,0 +525,0 @@ expect(result).to.equal(10);

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc