Skip to content

Commit

Permalink
Use hash instead of 3 keys
Browse files Browse the repository at this point in the history
  • Loading branch information
João Barbosa committed Feb 1, 2017
1 parent 6361f2d commit 5bb66e7
Showing 1 changed file with 18 additions and 24 deletions.
42 changes: 18 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function Limiter(opts) {
assert(this.db, '.db required');
this.max = opts.max || 2500;
this.duration = opts.duration || 3600000;
this.prefix = 'limit:' + this.id + ':';
this.key = 'limit:' + this.id;
}

/**
Expand All @@ -46,21 +46,17 @@ Limiter.prototype.inspect = function () {
/**
* Get values and header / status code and invoke `fn(err, info)`.
*
* redis is populated with the following keys
* redis is populated with the following key
* that expire after N seconds:
*
* - limit:<id>:count
* - limit:<id>:limit
* - limit:<id>:reset
* - limit:<id> (count, limit, reset)
*
* @param {Function} fn
* @api public
*/

Limiter.prototype.get = function (fn) {
var count = this.prefix + 'count';
var limit = this.prefix + 'limit';
var reset = this.prefix + 'reset';
var key = this.key;
var duration = this.duration;
var max = this.max;
var db = this.db;
Expand All @@ -69,9 +65,10 @@ Limiter.prototype.get = function (fn) {
var ex = (Date.now() + duration) / 1000 | 0;

db.multi()
.set([count, max, 'PX', duration, 'NX'])
.set([limit, max, 'PX', duration, 'NX'])
.set([reset, ex, 'PX', duration, 'NX'])
.hset([key, 'count', max])
.hsetnx([key, 'limit', max])
.hsetnx([key, 'reset', ex])
.pexpire([key, duration])
.exec(function (err, res) {
if (err) return fn(err);

Expand All @@ -88,25 +85,23 @@ Limiter.prototype.get = function (fn) {
}

function decr(res) {
var n = ~~res[0];
var max = ~~res[1];
var ex = ~~res[2];
var n = ~~res.count;
var max = ~~res.limit;
var ex = ~~res.reset;
var dateNow = Date.now();

if (n <= 0) return done();
if (n === 0) return done();

function done() {
fn(null, {
total: max,
remaining: n < 0 ? 0 : n,
remaining: n,
reset: ex
});
}

db.multi()
.set([count, n - 1, 'PX', ex * 1000 - dateNow, 'XX'])
.pexpire([limit, ex * 1000 - dateNow])
.pexpire([reset, ex * 1000 - dateNow])
.hincrby([key, 'count', -1])
.exec(function (err, res) {
if (err) return fn(err);
if (isFirstReplyNull(res)) return mget();
Expand All @@ -116,13 +111,12 @@ Limiter.prototype.get = function (fn) {
}

function mget() {
db.watch([count], function (err) {
db.watch([key], function (err) {
if (err) return fn(err);
db.mget([count, limit, reset], function (err, res) {
db.hgetall([key], function (err, res) {
if (err) return fn(err);
if (!res[0] && res[0] !== 0) return create();

decr(res);
if (res && res.count >= 0) return decr(res);
create();
});
});
}
Expand Down

0 comments on commit 5bb66e7

Please sign in to comment.