rate-limiter-flexible
Advanced tools
Comparing version 0.5.1 to 0.6.0
@@ -8,2 +8,3 @@ module.exports = class RateLimiterAbstract { | ||
* execEvenly: false, // Execute allowed actions evenly over duration | ||
* keyPrefix: 'rlflx', | ||
* } | ||
@@ -15,2 +16,3 @@ */ | ||
this.execEvenly = opts.execEvenly; | ||
this.keyPrefix = opts.keyPrefix; | ||
} | ||
@@ -42,6 +44,20 @@ | ||
static getKey(key) { | ||
return `rlflx:${key}`; | ||
get keyPrefix() { | ||
return this._keyPrefix; | ||
} | ||
set keyPrefix(value) { | ||
if (typeof value === 'undefined') { | ||
value = 'rlflx'; | ||
} | ||
if (typeof value !== 'string') { | ||
throw new Error("keyPrefix must be string"); | ||
} | ||
this._keyPrefix = value; | ||
} | ||
getKey(key) { | ||
return this.keyPrefix + ':' + key; | ||
} | ||
consume() { | ||
@@ -48,0 +64,0 @@ throw new Error("You have to implement the method 'consume'!"); |
@@ -1,6 +0,6 @@ | ||
const RateLimiterInterface = require('./RateLimiterAbstract'); | ||
const RateLimiterAbstract = require('./RateLimiterAbstract'); | ||
const MemoryStorage = require('./component/MemoryStorage/MemoryStorage'); | ||
const RateLimiterRes = require('./RateLimiterRes'); | ||
class RateLimiterMemory extends RateLimiterInterface { | ||
class RateLimiterMemory extends RateLimiterAbstract { | ||
constructor(opts = {}) { | ||
@@ -19,3 +19,3 @@ super(opts); | ||
return new Promise((resolve, reject) => { | ||
const rlKey = RateLimiterInterface.getKey(key); | ||
const rlKey = this.getKey(key); | ||
const isFirstInDuration = this._memoryStorage.get(rlKey) === null; | ||
@@ -40,3 +40,3 @@ const storageRes = this._memoryStorage.incrby(rlKey, pointsToConsume, this.duration); | ||
penalty(key, points = 1) { | ||
const rlKey = RateLimiterInterface.getKey(key); | ||
const rlKey = this.getKey(key); | ||
return new Promise((resolve, reject) => { | ||
@@ -49,3 +49,3 @@ const res = this._memoryStorage.incrby(rlKey, points, this.duration); | ||
reward(key, points = 1) { | ||
const rlKey = RateLimiterInterface.getKey(key); | ||
const rlKey = this.getKey(key); | ||
return new Promise((resolve, reject) => { | ||
@@ -52,0 +52,0 @@ const res = this._memoryStorage.incrby(rlKey, -points, this.duration); |
@@ -12,3 +12,3 @@ const expect = require('chai').expect; | ||
.then(() => { | ||
const res = rateLimiterMemory._memoryStorage.get(RateLimiterMemory.getKey(testKey)); | ||
const res = rateLimiterMemory._memoryStorage.get(rateLimiterMemory.getKey(testKey)); | ||
expect(res.consumedPoints).to.equal(1); | ||
@@ -70,3 +70,3 @@ done(); | ||
.then(() => { | ||
const res = rateLimiterMemory._memoryStorage.get(RateLimiterMemory.getKey(testKey)); | ||
const res = rateLimiterMemory._memoryStorage.get(rateLimiterMemory.getKey(testKey)); | ||
expect(res.consumedPoints).to.equal(2); | ||
@@ -91,3 +91,3 @@ done(); | ||
.then(() => { | ||
const res = rateLimiterMemory._memoryStorage.get(RateLimiterMemory.getKey(testKey)); | ||
const res = rateLimiterMemory._memoryStorage.get(rateLimiterMemory.getKey(testKey)); | ||
expect(res.consumedPoints).to.equal(0); | ||
@@ -104,2 +104,10 @@ done(); | ||
}); | ||
it('use keyPrefix from options', () => { | ||
const testKey = 'key'; | ||
const keyPrefix = 'test'; | ||
const rateLimiterMemory = new RateLimiterMemory({keyPrefix: keyPrefix, points: 1, duration: 5}); | ||
expect(rateLimiterMemory.getKey(testKey)).to.equal('test:key'); | ||
}); | ||
}); |
@@ -128,3 +128,3 @@ const RateLimiterAbstract = require('./RateLimiterAbstract'); | ||
return new Promise((resolve, reject) => { | ||
const rlKey = RateLimiterAbstract.getKey(key); | ||
const rlKey = this.getKey(key); | ||
@@ -153,3 +153,3 @@ if (this.blockOnPointsConsumed > 0) { | ||
penalty(key, points = 1) { | ||
const rlKey = RateLimiterAbstract.getKey(key); | ||
const rlKey = this.getKey(key); | ||
return new Promise((resolve, reject) => { | ||
@@ -167,3 +167,3 @@ this.redis.incrby(rlKey, points, (err, value) => { | ||
reward(key, points = 1) { | ||
const rlKey = RateLimiterAbstract.getKey(key); | ||
const rlKey = this.getKey(key); | ||
return new Promise((resolve, reject) => { | ||
@@ -170,0 +170,0 @@ this.redis.incrby(rlKey, -points, (err, value) => { |
@@ -45,3 +45,3 @@ const expect = require('chai').expect; | ||
.then(() => { | ||
redisMockClient.get(RateLimiterRedis.getKey(testKey), (err, consumedPoints) => { | ||
redisMockClient.get(rateLimiter.getKey(testKey), (err, consumedPoints) => { | ||
if (!err) { | ||
@@ -103,3 +103,3 @@ expect(consumedPoints).to.equal('1'); | ||
.then(() => { | ||
redisMockClient.get(RateLimiterRedis.getKey(testKey), (err, consumedPoints) => { | ||
redisMockClient.get(rateLimiter.getKey(testKey), (err, consumedPoints) => { | ||
if (!err) { | ||
@@ -127,3 +127,3 @@ expect(consumedPoints).to.equal('2'); | ||
.then(() => { | ||
redisMockClient.get(RateLimiterRedis.getKey(testKey), (err, consumedPoints) => { | ||
redisMockClient.get(rateLimiter.getKey(testKey), (err, consumedPoints) => { | ||
if (!err) { | ||
@@ -281,3 +281,3 @@ expect(consumedPoints).to.equal('0'); | ||
.then((res) => { | ||
redisMockClient.get(RateLimiterRedis.getKey(testKey), (err, consumedPoints) => { | ||
redisMockClient.get(rateLimiter.getKey(testKey), (err, consumedPoints) => { | ||
if (!err) { | ||
@@ -310,3 +310,3 @@ expect(consumedPoints).to.equal('1'); | ||
.then((res) => { | ||
redisMockClient.get(RateLimiterRedis.getKey(testKey), (err, consumedPoints) => { | ||
redisMockClient.get(rateLimiter.getKey(testKey), (err, consumedPoints) => { | ||
if (!err) { | ||
@@ -323,2 +323,10 @@ expect(consumedPoints).to.equal('1'); | ||
it('use keyPrefix from options', () => { | ||
const testKey = 'key'; | ||
const keyPrefix = 'test'; | ||
const rateLimiter = new RateLimiterRedis({keyPrefix: keyPrefix, redis: redisClientClosed}); | ||
expect(rateLimiter.getKey(testKey)).to.equal('test:key'); | ||
}); | ||
}); |
{ | ||
"name": "rate-limiter-flexible", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"description": "Flexible API rate limiter backed by Redis for distributed node.js applications", | ||
@@ -36,4 +36,4 @@ "main": "index.js", | ||
"mocha": "^5.1.1", | ||
"redis-mock": "animir/redis-mock" | ||
"redis-mock": "^0.22.0" | ||
} | ||
} |
@@ -82,2 +82,3 @@ [![Build Status](https://travis-ci.org/animir/node-rate-limiter-flexible.png)](https://travis-ci.org/animir/node-rate-limiter-flexible) | ||
redis: redisClient, | ||
keyPrefix: 'rlflx', // useful for multiple limiters | ||
points: 5, // Number of points | ||
@@ -108,3 +109,3 @@ duration: 5, // Per second(s) | ||
// or rise number of points for current duration | ||
rateLimiterRedis.reward(remoteAddress, 2); | ||
rateLimiterRedis.reward(remoteAddress, 2) | ||
.then((consumedPoints) => {}); | ||
@@ -134,2 +135,3 @@ }) | ||
{ | ||
keyPrefix: 'rlflx', | ||
points: 1, // 1 is fair if you have 5 workers and 1 cluster, all workers will limit it to 5 in sum | ||
@@ -147,2 +149,4 @@ duration: 5, | ||
* `keyPrefix` `Default: 'rlflx''` If you need to create several limiters for different purpose | ||
* `points` `Default: 4` Maximum number of points can be consumed over duration | ||
@@ -149,0 +153,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
89269
959
215