throttled-request
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -59,2 +59,10 @@ /* | ||
ThrottledRequest.prototype.throttleDelay = function() { | ||
if (isFunction(this.config.milliseconds)) { | ||
return this.config.milliseconds(); | ||
} | ||
return this.config.milliseconds; | ||
}; | ||
ThrottledRequest.prototype.throttleRequest = function () { | ||
@@ -68,6 +76,8 @@ var self = this | ||
if (!this.startedAt) this.startedAt = Date.now(); | ||
if (Date.now() - this.startedAt > this.config.milliseconds) { | ||
if (!this.milliseconds) this.milliseconds = this.throttleDelay(); | ||
if (Date.now() - this.startedAt >= this.milliseconds) { | ||
this.sentRequests = 0; | ||
this.startedAt = Date.now(); | ||
this.milliseconds = this.throttleDelay(); | ||
}; | ||
@@ -99,3 +109,3 @@ | ||
self.throttleRequest.apply(self, args); | ||
}, this.config.milliseconds - (Date.now() - this.startedAt)); | ||
}, this.milliseconds - (Date.now() - this.startedAt)); | ||
@@ -105,2 +115,7 @@ return requestMiddleware; | ||
function isFunction(value) { | ||
return typeof value == 'function'; | ||
} | ||
module.exports = ThrottledRequest; |
{ | ||
"name": "throttled-request", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "Node.js module to easily throttle HTTP requests", | ||
"author": "Daniel López <danypype@gmail.com>", | ||
"scripts": { | ||
"test": "./node_modules/.bin/mocha" | ||
"test": "mocha" | ||
}, | ||
@@ -30,4 +30,5 @@ "main": "./lib/index.js", | ||
"nock": "^0.52.4", | ||
"request": "^2.51.0" | ||
"request": "^2.51.0", | ||
"sinon": "^1.12.2" | ||
} | ||
} |
@@ -27,2 +27,16 @@ #throttled-request | ||
Or you may use a configurable throttle by providing a function that returns the next delay, in milliseconds: | ||
```javascript | ||
var request = require('request') | ||
, throttledRequest = require('throttled-request')(request); | ||
throttledRequest.configure({ | ||
requests: 1, | ||
milliseconds: function() { | ||
var minSeconds = 5, maxSeconds = 15; | ||
return Math.floor((Math.random() * (maxSeconds - minSeconds) + minSeconds) * 1000); // in milliseconds | ||
} | ||
});//This will throttle the requests so no more than 1 is made every 5 to 15 seconds (random delay) | ||
``` | ||
Then you can use `throttledRequest` just as you use [request](https://github.com/request/request): passing a callback, or as a stream. | ||
@@ -29,0 +43,0 @@ |
var ThrottledRequest = require("../") | ||
, nock = require("nock") | ||
, sinon = require("sinon") | ||
, async = require("async"); | ||
describe("ThrottledRequest", function () { | ||
var clock; | ||
nock.disableNetConnect(); | ||
@@ -23,4 +26,11 @@ | ||
describe("throttling", function () { | ||
beforeEach(function () { | ||
clock = sinon.useFakeTimers(Date.now()); | ||
}); | ||
afterEach(function() { | ||
clock.restore(); | ||
}); | ||
it("sends 3 requests every half a second", function (done) { | ||
this.timeout(4000) | ||
var self = this; | ||
@@ -56,6 +66,9 @@ | ||
//After half a second | ||
setTimeout(function () { | ||
expect(self.request).to.have.been.called.exactly(6); | ||
}, 500); | ||
clock.tick(500); | ||
expect(self.request).to.have.been.called.exactly(6); | ||
//After another half a second | ||
clock.tick(500); | ||
//When all requests have finished | ||
@@ -73,2 +86,4 @@ function onEnd (error) { | ||
beforeEach(function () { | ||
clock = sinon.useFakeTimers(Date.now()); | ||
//Mock 2 calls to the server | ||
@@ -84,2 +99,6 @@ mockTimes(2); | ||
afterEach(function() { | ||
clock.restore(); | ||
}); | ||
it("allows to use request with callback", function (done) { | ||
@@ -91,3 +110,3 @@ this.throttledRequest("http://ping.com", function (error, response, body) { | ||
}); | ||
this.throttledRequest({uri: "http://ping.com"}, function (error, response, body) { | ||
@@ -99,2 +118,4 @@ if (error) return done(error); | ||
}); | ||
clock.tick(100); | ||
}); | ||
@@ -131,5 +152,73 @@ | ||
}); | ||
clock.tick(100); | ||
}); | ||
}); | ||
describe("configurable delay", function() { | ||
beforeEach(function () { | ||
clock = sinon.useFakeTimers(Date.now()); | ||
//Mock 2 calls to the server | ||
mockTimes(3); | ||
var delay = [1000, 2000, 3000]; | ||
//Configure throttledRequest | ||
this.throttledRequest.configure({ | ||
requests: 1, | ||
milliseconds: function() { | ||
return delay.shift(); | ||
} | ||
}); | ||
}); | ||
afterEach(function() { | ||
clock.restore(); | ||
}); | ||
it("allows configurable delay via provided user function", function(done) { | ||
var self = this; | ||
var requests = []; | ||
for (var i = 0; i < 4; i++) { | ||
requests.push(function (callback) { | ||
self.throttledRequest({uri: "http://ping.com"}, function (error, response, body) { | ||
if (error) return done(error); | ||
expect(response.statusCode).to.equal(200); | ||
expect(body).to.equal("pong"); | ||
callback(); | ||
}); | ||
}); | ||
}; | ||
//Mock 3 calls to the server | ||
mockTimes(4); | ||
//Send 3 requests at the same time | ||
async.parallel(requests, onEnd); | ||
expect(this.request).to.have.been.called.exactly(1); | ||
//After one second | ||
clock.tick(1000); | ||
expect(self.request).to.have.been.called.exactly(2); | ||
//After another two seconds | ||
clock.tick(2000); | ||
expect(self.request).to.have.been.called.exactly(3); | ||
//Finally, after another 3 seconds | ||
clock.tick(3000); | ||
expect(self.request).to.have.been.called.exactly(4); | ||
//When all requests have finished | ||
function onEnd (error) { | ||
if (error) return done(error); | ||
expect(self.request).to.have.been.called.exactly(4); | ||
done(); | ||
}; | ||
}); | ||
}); | ||
describe("handling errors", function () { | ||
@@ -136,0 +225,0 @@ before(function () { |
17837
384
118
7