@@ -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
6058Limiter . 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+ }
0 commit comments