Lets say I have a message queue, it would be much longer in production
var mq = ["A","B","C"];
I want to send each message out over UDP BUT I need to rate limit it as to not overwhelm the receiver.
while(mq.length)
{
limit.removeTokens(1,function(){
var m = mq.pop();
client.send(m,0,m.length,port,ip, function(err,bytes){
console.log("sent");
});
});
}
As I understand it, the while loop will block, and will not actually send out data. It actually ends up with a memory alloc error cause it keeps spinning up.
I tried using process.nextTick() but it ends up with a recursion error.
What is the proper way to go about this?
Thanks!
This is something that can be modeled with a simple queue. Here's an example:
var mq = ["A","B","C"];
// create a queue with the max concurrent jobs to run
// and a function that starts a new job
var queue = new Queue(5, function(item, callback){
client.send(item, 0, item.length, ip, function(){
// signal that we're done, and another item can start
callback();
});
});
// add an array of items to the queue
mq.forEach(queue.add);
function Queue(max, handler){
var queueItems = [];
// we keep a count of the number of unused job slots we have
// when this is more than 0, a new job will start
this.available = max;
this.add = function(item){
queueItems.push(item);
process.nextTick(function(){
this.maybeRunActions();
}.bind(this));
}.bind(this);
// this will run actions if both:
// - we have actions to run
// - we have unused slots
this.maybeRunActions = function(){
while (this.available > 0 && queueItems.length > 0) {
this.available -= 1;
// call the handler passed to new Queue, which kicks of the job
// and tells the queue when the job is complete
handler(queueItems.shift(), function(){
this.available += 1;
this.maybeRunActions();
}.bind(this));
}
}
}