From 520eeff4f4ceb847fc2d17dd2dbd2847e217ed3e Mon Sep 17 00:00:00 2001 From: Krishna Kalubandi Date: Tue, 31 Jan 2017 15:24:21 +0530 Subject: [PATCH 1/4] fixes #29 --- index.js | 23 ++++++++++++----------- package.json | 3 +++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 2b1c370..fc53d96 100644 --- a/index.js +++ b/index.js @@ -36,11 +36,11 @@ function Limiter(opts) { * @api public */ -Limiter.prototype.inspect = function () { - return ''; +Limiter.prototype.inspect = function() { + return ''; }; /** @@ -57,7 +57,7 @@ Limiter.prototype.inspect = function () { * @api public */ -Limiter.prototype.get = function (fn) { +Limiter.prototype.get = function(fn) { var count = this.prefix + 'count'; var limit = this.prefix + 'limit'; var reset = this.prefix + 'reset'; @@ -72,7 +72,7 @@ Limiter.prototype.get = function (fn) { .set([count, max, 'PX', duration, 'NX']) .set([limit, max, 'PX', duration, 'NX']) .set([reset, ex, 'PX', duration, 'NX']) - .exec(function (err, res) { + .exec(function(err, res) { if (err) return fn(err); // If the request has failed, it means the values already @@ -104,10 +104,11 @@ Limiter.prototype.get = function (fn) { } db.multi() - .set([count, n - 1, 'PX', ex * 1000 - dateNow, 'XX']) + .decr(count) + .pexpire([count, ex * 1000 - dateNow]) .pexpire([limit, ex * 1000 - dateNow]) .pexpire([reset, ex * 1000 - dateNow]) - .exec(function (err, res) { + .exec(function(err, res) { if (err) return fn(err); if (isFirstReplyNull(res)) return mget(); n = n - 1; @@ -116,9 +117,9 @@ Limiter.prototype.get = function (fn) { } function mget() { - db.watch([count], function (err) { + db.watch([count], function(err) { if (err) return fn(err); - db.mget([count, limit, reset], function (err, res) { + db.mget([count, limit, reset], function(err, res) { if (err) return fn(err); if (!res[0] && res[0] !== 0) return create(); diff --git a/package.json b/package.json index db49ca4..8b5dc2f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,9 @@ "limiter", "limit" ], + "scripts" : { + "test" : "mocha" + }, "dependencies": {}, "devDependencies": { "ioredis": "1.15.1", From 110c61a330c7f45841a927ef389690321df16d98 Mon Sep 17 00:00:00 2001 From: Krishna Kalubandi Date: Tue, 31 Jan 2017 15:41:14 +0530 Subject: [PATCH 2/4] fixed n value --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index fc53d96..3d13253 100644 --- a/index.js +++ b/index.js @@ -111,7 +111,7 @@ Limiter.prototype.get = function(fn) { .exec(function(err, res) { if (err) return fn(err); if (isFirstReplyNull(res)) return mget(); - n = n - 1; + n = Array.isArray(res[0]) ? ~~res[0][1] : ~~res[0]; done(); }); } From e0dc931e59ddab3741b4237bc669693c576fd578 Mon Sep 17 00:00:00 2001 From: Krishna Kalubandi Date: Wed, 1 Feb 2017 14:33:26 +0530 Subject: [PATCH 3/4] added tests --- package.json | 5 +++-- test/index.js | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 8b5dc2f..5f29d3c 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ "limiter", "limit" ], - "scripts" : { - "test" : "mocha" + "scripts": { + "test": "mocha" }, "dependencies": {}, "devDependencies": { + "async": "2.1.4", "ioredis": "1.15.1", "mocha": "*", "redis": "2.6.0-1", diff --git a/test/index.js b/test/index.js index 5419f81..bda3fc6 100644 --- a/test/index.js +++ b/test/index.js @@ -1,11 +1,12 @@ require('should'); -var Limiter = require('..'); +var Limiter = require('..'), + async = require('async'); // Uncomment the following line if you want to see // debug logs from the node-redis module. //redis.debug_mode = true; -['redis', 'ioredis'].forEach(function (redisModuleName) { +['redis', 'ioredis'].forEach(function(redisModuleName) { var redisModule = require(redisModuleName); var db = require(redisModuleName).createClient(); describe('Limiter with ' + redisModuleName, function() { @@ -146,7 +147,7 @@ var Limiter = require('..'); .pttl(['limit:something:count']) .pttl(['limit:something:limit']) .pttl(['limit:something:reset']) - .exec(function (err, res) { + .exec(function(err, res) { if (err) return done(err); var ttlCount = (typeof res[0] === 'number') ? res[0] : res[0][1]; var ttlLimit = (typeof res[1] === 'number') ? res[1] : res[1][1]; @@ -211,7 +212,8 @@ var Limiter = require('..'); if (err) { done(err); - } else { + } + else { responses.forEach(function(res) { res[1].remaining.should.equal(left < 0 ? 0 : left); left--; @@ -230,7 +232,8 @@ var Limiter = require('..'); limits[0].get(function(err, res) { if (err) { done(err); - } else { + } + else { res.remaining.should.equal(left--); // Simulate multiple concurrent requests. @@ -241,5 +244,31 @@ var Limiter = require('..'); }); }); }); + + describe('when limiter is called in parallel by multiple clients', function() { + var max = 6, + limiter; + + limiter = new Limiter({ + duration: 10000, + max: max, + id: 'asyncsomething', + db: redisModule.createClient() + }); + + it('should set the count properly without race conditions', function(done) { + async.times(max, function(n, next) { + limiter.get(next); + }, + function(errs, limits) { + + limits.forEach(function(limit) { + limit.remaining.should.equal(max--); + }); + done(); + + }); + }); + }) }); }); From 2c4f277307e5eae4cc56ea80dfb08854e0063817 Mon Sep 17 00:00:00 2001 From: kp96 Date: Mon, 6 Feb 2017 18:03:13 +0530 Subject: [PATCH 4/4] test for node 0.1 --- History.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/History.md b/History.md index 9ce5e02..d79c084 100644 --- a/History.md +++ b/History.md @@ -11,4 +11,4 @@ ## v1.0.1 / 2014-03-14 -* fix race condition resetting the keys \ No newline at end of file +* fix race condition resetting the keys.