Skip to content

Commit

Permalink
Fixing variable naming bugs in TokenBucket, adding basic unit tests f…
Browse files Browse the repository at this point in the history
…or TokenBucket
  • Loading branch information
jhurliman committed Jul 17, 2012
1 parent c1ad90f commit 1e2b4f9
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build
.lock-wscript
.DS_Store
node_modules
16 changes: 8 additions & 8 deletions lib/tokenBucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ TokenBucket.prototype = {
* false.
*/
removeTokens: function(count, callback) {
var self = this;

// Is this an infinite size bucket?
if (!this.maxBurst) {
if (!this.bucketSize) {
callback(null, count, Number.POSITIVE_INFINITY);
return true;
}
Expand All @@ -77,15 +79,13 @@ TokenBucket.prototype = {
// How long do we need to wait to make up the difference in tokens?
var waitInterval = Math.ceil(
(count - this.content) * (this.interval / this.tokensPerInterval));
setTimeout(function() { removeTokens(count, callback); }, waitInterval);
setTimeout(function() { self.removeTokens(count, callback); }, waitInterval);
return false;
}

if (parent) {
var self = this;

if (this.parentBucket) {
// Remove the requested from the parent bucket first
return parent.removeTokens(count, function(err, remainingTokens) {
return this.parentBucket.removeTokens(count, function(err, remainingTokens) {
if (err) {
callback(err, null);
return;
Expand All @@ -101,7 +101,7 @@ TokenBucket.prototype = {
} else {
// Remove the requested tokens from this bucket and fire the callback
this.content -= count;
callback(null, self.content);
callback(null, this.content);
return true;
}
},
Expand All @@ -121,7 +121,7 @@ TokenBucket.prototype = {
this.lastDrip = now;

var dripAmount = deltaMS * (this.tokensPerInterval / this.interval);
this.content = Math.min(this.content + dripAmount, maxBurst);
this.content = Math.min(this.content + dripAmount, this.bucketSize);
}
};

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"version": "0.0.2",
"author": "John Hurliman <jhurliman@cull.tv>",
"dependencies": { },
"devDependencies": { },
"devDependencies": {
"assert": "0.4.9",
"vows": "0.6.3"
},
"keywords": ["rate", "limiting", "throttling"],
"repository": "git://github.com/jhurliman/node-rate-limiter",
"bugs": { "url": "http://github.com/jhurliman/node-rate-limiter/issues" },
Expand Down
70 changes: 70 additions & 0 deletions tests/tokenbucket-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
var vows = require('vows');
var assert = require('assert');

var TIMING_EPSILON = 10;

var TokenBucket = require('../lib/tokenBucket');
var gBucket;
var gStart;

vows.describe('TokenBucket').addBatch({
'capacity 10, 1 per 100ms': {
topic: new TokenBucket(10, 1, 100),

'is initialized empty': function(bucket) {
gBucket = bucket;
assert.equal(bucket.bucketSize, 10);
assert.equal(bucket.tokensPerInterval, 1);
assert.equal(bucket.content, 0);
},
'removing 10 tokens': {
topic: function(bucket) {
gStart = +new Date();
bucket.removeTokens(10, this.callback);
},
'takes 1 second': function(remainingTokens) {
var duration = +new Date() - gStart;
var diff = Math.abs(1000 - duration);
assert.ok(diff < TIMING_EPSILON, diff+'');
assert.equal(remainingTokens, 0);
},
'and removing another 10 tokens': {
topic: function() {
gStart = +new Date();
assert.equal(gBucket.content, 0);
gBucket.removeTokens(10, this.callback);
},
'takes 1 second': function() {
var duration = +new Date() - gStart;
var diff = Math.abs(1000 - duration);
assert.ok(diff < TIMING_EPSILON, diff+'');
}
},
'and waiting 2 seconds': {
topic: function() {
var self = this;
setTimeout(function() {
gStart = +new Date();
gBucket.removeTokens(10, self.callback);
}, 2000);
},
'gives us only 10 tokens': function(remainingTokens) {
var duration = +new Date() - gStart;
assert.ok(duration < TIMING_EPSILON, duration+'');
assert.equal(remainingTokens, 0);
},
'and removing 1 token': {
topic: function() {
gStart = +new Date();
gBucket.removeTokens(1, this.callback);
},
'takes 100ms': function() {
var duration = +new Date() - gStart;
var diff = Math.abs(100 - duration);
assert.ok(diff < TIMING_EPSILON, diff+'');
}
}
}
}
},
}).export(module);

0 comments on commit 1e2b4f9

Please sign in to comment.