我想以下列方式处理队列:
节点进程还为简单的网站(express)提供服务。但该网站的请求很少。大多数工作都将在处理队列
时完成目标是能够比每个流程只能弹出一个流程更好地使每个流程饱和 一次任务。由于任务涉及相当多的等待外部服务我 认为如果没有在" parallell"中处理它们将是一种浪费。 (我知道它并不是真正的平行)。 我认为五个左右是极限,但这需要在一段时间后进行调整。
粗伪代码:
loopForewer {
popNextTaskFromQueue(function(task) {
if(task && concurrentTasks <= limit) {
concurrentTasks ++;
processTask(task, function(err) {
concurrentTasks --;
})
})
}
}
我该如何解决这个问题?
提前致谢。 //迈克尔
编辑:
我将详细介绍一下有关async.parallelLimit的Pauls建议和使用async.queue的尝试。我希望通过编辑我自己的问题来做到这一点。
async.parallelLimit:
实际上,我不知道这是怎么适合的。但我是Node和JavaScript的初学者,我可能错过了一些东西。
我无法在没有首先从MongoDB中的队列中获取所有可用任务的情况下看到如何保持进程饱和(即填充5个任务)。但是,如果我完成了所有任务,那么除了五个之外的所有任务都将等待而不是由另一个节点进程处理。
async.queue:
怎么看待这个?
q = async.queue.., 5) //create a queue with concurrency limit 5
dbQ = someQueueWithMongoStorage..
while(true) {
nextTick(function() {
if (!q.saturated) {
dbQ.getTask(function(err, task) {
if (task) q.push(task)
})
}
})
}
答案 0 :(得分:1)
我继续尝试了async.queue概念。我将使用(种类)以下解决方案。请插入并告诉我,如果我做了一些愚蠢的事情,即锁定某些东西。当dbQ为空时,我会每隔一秒点击一次数据库,但这对我没用。
var limit = 5;
var q = async.queue(function(task, callback) {
console.log('Processing ' + task.payload.task);
setTimeout(function() {
dbQ.ack(task.ack, function(err) {
console.log('Finished ' + task.id);
callback();
})
}, 1000);
}, limit);
function enqueueTasks() {
console.log('QueueLength: ' + q.length() + ', Running tasks: ' + q.running());
if (q.length() < limit) {
dbQ.get(function(err, task) {
if (task) {
console.log('Enqueing task ' + task.id)
q.push(task, function(err) {
});
enqueueTasks();
} else {
console.log('dbQ is empty, taking a 1 second nap')
setTimeout(function() {
enqueueTasks();
}, 1000);
}
});
} else {
console.log('Queue length limit hit, taking a 1 second nap')
setTimeout(function() {
enqueueTasks();
}, 1000);
}
}
enqueueTasks();
答案 1 :(得分:0)
查看async
库,特别是parallelLimit
函数。
https://github.com/caolan/async#parallellimittasks-limit-callback