diff --git a/index.js b/index.js index d85e42c..5663cde 100644 --- a/index.js +++ b/index.js @@ -69,15 +69,21 @@ Limiter.prototype.get = function (fn) { .zcard([key]) .zadd([key, now, now]) .zrange([key, 0, 0]) + .zrange([key, -max, -max]) .pexpire([key, duration]) .exec(function (err, res) { if (err) return fn(err); - var count = parseInt(Array.isArray(res[0]) ? res[1][1] : res[1]); - var oldest = parseInt(Array.isArray(res[0]) ? res[3][1] : res[3]); + + var isIoRedis = Array.isArray(res[0]); + var count = parseInt(isIoRedis ? res[1][1] : res[1]); + var oldest = parseInt(isIoRedis ? res[3][1] : res[3]); + var oldestInRange = parseInt(isIoRedis ? res[4][1] : res[4]); + var resetMicro = (Number.isNaN(oldestInRange) ? oldest : oldestInRange) + duration * 1000; + fn(null, { remaining: count < max ? max - count : 0, - reset: Math.floor((oldest + duration * 1000) / 1000000), - resetMs: Math.floor((oldest + duration * 1000) / 1000), + reset: Math.floor(resetMicro / 1000000), + resetMs: Math.floor(resetMicro / 1000), total: max }); }); diff --git a/test/index.js b/test/index.js index 26d2fcc..0f95059 100644 --- a/test/index.js +++ b/test/index.js @@ -88,23 +88,43 @@ var Limiter = require('..'), }); describe('when the limit is exceeded', function() { - it('should retain .remaining at 0', function(done) { - var limit = new Limiter({ + var limit; + + beforeEach(function (done) { + limit = new Limiter({ max: 2, id: 'something', db: db }); + + limit.get(function() { + limit.get(function() { + done(); + }); + }); + }); + + it('should retain .remaining at 0', function(done) { limit.get(function(err, res) { - res.remaining.should.equal(2); + // function caller should reject this call + res.remaining.should.equal(0); + done(); + }); + }); + + it('should return an increasing reset time after each call', function (done) { + setTimeout(function () { limit.get(function(err, res) { - res.remaining.should.equal(1); - limit.get(function(err, res) { - // function caller should reject this call - res.remaining.should.equal(0); - done(); - }); + var originalResetMs = res.resetMs; + + setTimeout(function() { + limit.get(function (err, res) { + res.resetMs.should.be.greaterThan(originalResetMs); + done(); + }); + }, 10); }); - }); + }, 10); }); });