Bluebird-Queue Concurrency in Promise Queues not working as expected

巧了我就是萌 提交于 2019-12-24 03:30:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!