Skip to content

Commit 913081a

Browse files
author
João Barbosa
committed
Use hash instead of 3 keys
1 parent 6361f2d commit 913081a

File tree

4 files changed

+315
-32
lines changed

4 files changed

+315
-32
lines changed

index.js

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function Limiter(opts) {
2727
assert(this.db, '.db required');
2828
this.max = opts.max || 2500;
2929
this.duration = opts.duration || 3600000;
30-
this.prefix = 'limit:' + this.id + ':';
30+
this.key = 'limit:' + this.id;
3131
}
3232

3333
/**
@@ -46,21 +46,17 @@ Limiter.prototype.inspect = function () {
4646
/**
4747
* Get values and header / status code and invoke `fn(err, info)`.
4848
*
49-
* redis is populated with the following keys
49+
* redis is populated with the following key
5050
* that expire after N seconds:
5151
*
52-
* - limit:<id>:count
53-
* - limit:<id>:limit
54-
* - limit:<id>:reset
52+
* - limit:<id> (count, limit, reset)
5553
*
5654
* @param {Function} fn
5755
* @api public
5856
*/
5957

6058
Limiter.prototype.get = function (fn) {
61-
var count = this.prefix + 'count';
62-
var limit = this.prefix + 'limit';
63-
var reset = this.prefix + 'reset';
59+
var key = this.key;
6460
var duration = this.duration;
6561
var max = this.max;
6662
var db = this.db;
@@ -69,9 +65,10 @@ Limiter.prototype.get = function (fn) {
6965
var ex = (Date.now() + duration) / 1000 | 0;
7066

7167
db.multi()
72-
.set([count, max, 'PX', duration, 'NX'])
73-
.set([limit, max, 'PX', duration, 'NX'])
74-
.set([reset, ex, 'PX', duration, 'NX'])
68+
.hsetnx([key, 'count', max])
69+
.hsetnx([key, 'limit', max])
70+
.hsetnx([key, 'reset', ex])
71+
.pexpire([key, duration])
7572
.exec(function (err, res) {
7673
if (err) return fn(err);
7774

@@ -88,42 +85,43 @@ Limiter.prototype.get = function (fn) {
8885
}
8986

9087
function decr(res) {
91-
var n = ~~res[0];
92-
var max = ~~res[1];
93-
var ex = ~~res[2];
94-
var dateNow = Date.now();
88+
var n = parseInt(res.count);
89+
var max = parseInt(res.limit);
90+
var ex = parseInt(res.reset);
9591

96-
if (n <= 0) return done();
92+
if (n === 0) return done(0);
9793

98-
function done() {
94+
function done(n) {
9995
fn(null, {
10096
total: max,
101-
remaining: n < 0 ? 0 : n,
97+
remaining: n,
10298
reset: ex
10399
});
104100
}
105101

102+
// setTimeout(function() {
106103
db.multi()
107-
.set([count, n - 1, 'PX', ex * 1000 - dateNow, 'XX'])
108-
.pexpire([limit, ex * 1000 - dateNow])
109-
.pexpire([reset, ex * 1000 - dateNow])
104+
.hincrby([key, 'count', -1])
105+
.pexpire([key, ex * 1000 - Date.now()])
110106
.exec(function (err, res) {
111107
if (err) return fn(err);
112108
if (isFirstReplyNull(res)) return mget();
113-
n = n - 1;
114-
done();
109+
done(n - 1);
115110
});
111+
// }, 1000)
116112
}
117113

118114
function mget() {
119-
db.watch([count], function (err) {
115+
db.watch([key], function (err) {
120116
if (err) return fn(err);
121-
db.mget([count, limit, reset], function (err, res) {
117+
db.persist([key], function (err, res) {
122118
if (err) return fn(err);
123-
if (!res[0] && res[0] !== 0) return create();
124-
125-
decr(res);
126-
});
119+
if (res === 0) return create();
120+
db.hgetall([key], function (err, res) {
121+
if (err) return fn(err);
122+
decr(res);
123+
});
124+
})
127125
});
128126
}
129127

@@ -149,4 +147,4 @@ function isFirstReplyNull(replies) {
149147
!replies[0][1] :
150148
// node_redis
151149
!replies[0];
152-
}
150+
}

index2.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const redis = require('ioredis');
2+
const sleep = require('sleep-promise');
3+
4+
const db1 = redis.createClient();
5+
const db2 = redis.createClient();
6+
7+
(async () => {
8+
9+
for (let n=0; n < 100; n++) {
10+
console.log('-------------')
11+
console.log(await db1.set(['a', 10, 'PX', 1, 'NX']));
12+
// await sleep(1)
13+
console.log(await db1.get(['a']));
14+
}
15+
db1.quit();
16+
db2.quit();
17+
})();
18+

test/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ var Limiter = require('..');
9494
it('should reset', function(done) {
9595
this.timeout(5000);
9696
var limit = new Limiter({
97-
duration: 2000,
97+
duration: 500,
9898
max: 2,
9999
id: 'something',
100100
db: db
@@ -110,7 +110,7 @@ var Limiter = require('..');
110110
res.remaining.should.equal(2);
111111
done();
112112
});
113-
}, 3000);
113+
}, 1000);
114114
});
115115
});
116116
});

0 commit comments

Comments
 (0)