-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #31 from FamilySearch/interval
Implement requestInterval middleware; close #30
- Loading branch information
Showing
5 changed files
with
144 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* Enforce a minimum interval between requests. | ||
* See https://github.com/FamilySearch/fs-js-lite/issues/30 | ||
* | ||
* @param {Integer} interval Minimum time between requests, in milliseconds (ms) | ||
* @return {Function} middleware | ||
*/ | ||
module.exports = function(interval) { | ||
|
||
var lastRequestTime = 0, | ||
requestQueue = [], | ||
timer; | ||
|
||
/** | ||
* Add a request to the queue | ||
* | ||
* @param {Function} next The next method that was sent to the middleware with the request. | ||
*/ | ||
function enqueue(next) { | ||
requestQueue.push(next); | ||
startTimer(); | ||
} | ||
|
||
/** | ||
* Start the timer that checks for when a request in the queue is ready to go. | ||
* This fires every {interval} ms to enforce a minimum time between requests. | ||
* The actual time between requests may be longer. | ||
*/ | ||
function startTimer() { | ||
if(!timer) { | ||
timer = setInterval(checkQueue, interval); | ||
} | ||
} | ||
|
||
/** | ||
* Check to see if we're ready to send any requests. | ||
*/ | ||
function checkQueue() { | ||
if(!inInterval()) { | ||
if(requestQueue.length) { | ||
var next = requestQueue.shift(); | ||
sendRequest(next); | ||
} else if(timer) { | ||
clearInterval(timer); // No need to leave the timer running if we don't have any requests. | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Send a request by calling it's next() method and mark the current time so | ||
* that we can accurately enforce the interval. | ||
*/ | ||
function sendRequest(next) { | ||
lastRequestTime = Date.now(); | ||
next(); | ||
} | ||
|
||
/** | ||
* Returns true if the most recent request was less then {interval} ms in the past | ||
* | ||
* @return {Boolean} | ||
*/ | ||
function inInterval() { | ||
return Date.now() - lastRequestTime < interval; | ||
} | ||
|
||
return function(client, request, next) { | ||
|
||
// If there are any requests in the queue or if the previous request was issued | ||
// too recently then add this request to the queue. | ||
if(requestQueue.length || inInterval()) { | ||
enqueue(next); | ||
} | ||
|
||
else { | ||
sendRequest(next); | ||
} | ||
}; | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters