问题
I am using a bluebird-queue via NodeJS to queue HTTP endpoints as tasks. Each task has a 3-level Promise dependancy that has to resolve before it is complete.
One Task
GET -> endpoint 1 // returns promise
GET -> other endpoints in async // returns promise
POST -> final endpoint // return promise
I put 20,000 of these tasks into the bluebird-queue with queue.add()
and then subsequently call queue.start()
. All errors are caught and the handlers resolve the Promise
so the task can complete.
I have set concurrency to 50. My initial expectation is that the queue will process 50 at any given time but instead it waits for the first 50 to complete before starting on the next 50.
Unfortunately, some of these Requests can take up to 10 secs to complete - and if a single request takes longer to finish, the whole queue stalls until the Promise resolves.
If this is the expected behaviour, what can I do/use to ensure that tasks in the queue processes a max of 50 tasks at any given time, instead of per 50 at a time?
Here are my config settings:
var Queue = require('bluebird-queue'),
queue = new Queue({
concurrency: 50,
delay: 10, // ms
interval: 1 // ms not quite sure what this means
});
Any help is appreciated.
回答1:
After reading through the code for bluebird-queue
, it seems clear that that the behavior you're seeing regarding concurrency is what is expected. I agree that this is somewhat surprising. There does not appear to be any way to get the desired behavior.
I suggest trying promise-queue. Based on a quick reading of the code, it appears that it will work as you would expect.
回答2:
You should post an issue for at bluebird-queue
which is not coded by Petka Antonov. It's a custom project and it is rather raw at the moment. I was curious to play with it as your question sounded rather intriguing. I've made an example (below), that generates workers with different time to resolve. And it showed that bluebird-queue
behaves inconsistently. All but last set of items (as you described) are queued in one set, and all next set starts only when previous set is done. However this is not the case for the last set of items. You can play with N
and concurrency
to trace that
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);
});
};
来源:https://stackoverflow.com/questions/31128109/bluebird-queue-concurrency-in-promise-queues-not-working-as-expected