我通过NodeJS使用bluebird-queue
将HTTP端点排队为任务。每个任务都有一个3级Promise依赖,必须在完成之前解决。
一项任务
GET -> endpoint 1 // returns promise
GET -> other endpoints in async // returns promise
POST -> final endpoint // return promise
我将20,000个这些任务放入带有queue.add()
的bluebird队列,然后调用queue.start()
。捕获所有错误,处理程序解析Promise
,以便完成任务。
我已将并发设置为50.我最初的期望是队列将在任何给定时间处理50,而是在下一个50开始之前等待前50个完成。
不幸的是,其中一些请求最多可能需要10秒才能完成 - 如果单个请求需要更长时间才能完成,整个队列将停止运行,直到Promise结算。
如果这是预期的行为,我可以做什么/使用什么来确保队列中的任务在任何给定时间处理最多50个任务,而不是一次处理50个任务?
以下是我的配置设置:
var Queue = require('bluebird-queue'),
queue = new Queue({
concurrency: 50,
delay: 10, // ms
interval: 1 // ms not quite sure what this means
});
感谢任何帮助。
答案 0 :(得分:4)
在阅读bluebird-queue
的代码之后,很明显,您所看到的关于并发性的行为是预期的。我同意这有点令人惊讶。似乎没有任何方法可以达到预期的行为。
我建议您尝试promise-queue。基于对代码的快速阅读,它似乎可以像您期望的那样工作。
答案 1 :(得分:1)
您应该在bluebird-queue
发布未被Petka Antonov编码的问题。这是一个定制项目,目前相当原始。我很好奇地玩它,因为你的问题听起来很有趣。我已经做了一个例子(下面),它产生了具有不同时间来解决的工人。并且它表明bluebird-queue
表现不一致。除了最后一组项目(如您所述)之外的所有项目都在一组中排队,并且所有下一组项目仅在前一组完成时开始。然而,最后一组项目并非如此。您可以使用N
和concurrency
来追踪
var Promise = require("bluebird");
var Queue = require('bluebird-queue');
function formatTime(date){
function pad(value, width){
width = width || 2;
if(typeof value !== 'string') value = value.toString();
if(value.length < width) value = new Array(width - value.length + 1).join('0') + value;
return value;
}
return pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds()) + ':' + pad(date.getMilliseconds(), 3);
}
var N = 20;
var start = function(){
var queue = new Queue({
concurrency: 4,
delay: 10, // ms
interval: 1 // ms not quite sure what this means
});
for(var i = 0; i < N; i++){
var worker = function(number) {
return new Promise(function (resolve, reject) {
console.log(formatTime(new Date()) + ' Starting ' + number);
setTimeout(function () {
console.log(formatTime(new Date()) + ' Finished ' + number);
resolve(number);
}, 500 + (number % 2)*500);
});
}.bind(null, i);
queue.add(worker);
}
queue.start().then(function(arg){
console.log('All finished ' + arg);
});
};