Giter Club home page Giter Club logo

promise-queue's Introduction

promise-queue NPM Version Build Status Coverage Status

Promise-based queue

Installation

promise-queue can be installed using npm:

npm install promise-queue

Interface

  • new Queue(Number maxConcurrent, Number maxQueued): Queue
  • Queue#add(Function generator): Promise - adds function argument that generates a promise to the queue
  • Queue#getQueueLength(): Number - returns current length of buffer(added but not started promise generators) it <= maxQueued
  • Queue#getPendingLength(): Number - returns number of pending(concurrently running) promises it <= maxConcurrent

Example

Configure queue

By default Queue tries to use global Promises, but you can specify your own promises.

Queue.configure(require('vow').Promise);

Or use old-style promises approach:

Queue.configure(function (handler) {
    var dfd = $.Deferred();
    try {
        handler(dfd.resolve, dfd.reject, dfd.notify);
    } catch (e) {
        dfd.reject(e);
    }
    return dfd.promise();
});

Queue one by one example

var maxConcurrent = 1;
var maxQueue = Infinity;
var queue = new Queue(maxConcurrent, maxQueue);

app.get('/version/:user/:repo', function (req, res, next) {
    queue.add(function () {
        // Assume that this action is a way too expensive
        // Call of this function will be delayed on second request
        return downloadTarballFromGithub(req.params);
    })
    .then(parseJson('package.json'))
    .then(function (package) {
        res.send(package.version);
    })
    .catch(next);
});

Getting number of pending promises and queue(buffered promises) length

var maxConcurrent = 1;
var maxQueue = 1;
var queue = new Queue(maxConcurrent, maxQueue);

queue.add(function () {
    queue.getQueueLength() === 0;
    queue.getPendingLength() === 1;
    return somePromise();
});

queue.add(function () {
    queue.getQueueLength() === 0;
    queue.getPendingLength() === 0;
    return somePromise();
});

queue.getQueueLength() === 1;
queue.getPendingLength() === 1;

Live example

promise-queue's People

Contributors

adjohnson916 avatar andrewbranch avatar azproduction avatar mattpodwysocki avatar tonypee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

promise-queue's Issues

Promises Do Not Queue

On L109, inside thePromise the .add() method returns, you call ._dequeue(), assumedly to begin processing the Promises. What this causes is for every added Promise to dequeue as soon as it is actually queued.

This should only ever happen if there aren't any currently pending. If there are pending Promises, the recursive method will reach them eventually anyway. It would fail this test having them resolve in time order, not in the order they were queued.

Adding unshift to add to front of the queue

I'm a developer on the Thali Project at Microsoft, and we'd love to use your library. We currently have our own implementation of a PromiseQueue which has associated tests in testPromiseQueue.js.

What we're missing from this implementation is the ability to add items to the beginning of the queue as we file things in priority order. We'd rather just use something simple instead of a priority queue, so your project is perfect. All we'd want to add is something like the following?

    /**
     * @param {Function} promiseGenerator
     * @return {LocalPromise}
     */
    Queue.prototype.unshift = function (promiseGenerator) {
        var self = this;
        return new LocalPromise(function (resolve, reject, notify) {
            // Do not queue to much promises
            if (self.queue.length >= self.maxQueuedPromises) {
                reject(new Error('Queue limit reached'));
                return;
            }

            // Add to queue
            self.queue.unshift({
                promiseGenerator: promiseGenerator,
                resolve: resolve,
                reject: reject,
                notify: notify || noop
            });

            self._dequeue();
        });
    };

If you are amenable to adding it, with the choice of your name of course, then we'd happily file the PR with any documentation changes and tests included. Thoughts?

Exceptions/Errors are not caught/handled in any queue items beyond the first.

Specifically in nodejs (v0.12.7). I'm using Q for promises, but I think the same will happen with others.

Some sample code:

var Q = require('q');
var Queue = require('promise-queue');
Queue.configure(function (handler) {
    var deferred = Q.defer();
    try {
        handler(deferred.resolve, deferred.reject, deferred.notify);
    } catch (e) {
        console.error(e);
        deferred.reject(e);
    }
    return deferred.promise;
});

var maxConcurrent = 1;
var maxQueue = Infinity;
var serialQueue = new Queue(maxConcurrent, maxQueue);

serialQueue.add(function() {
     throw new Error('error that is caught');
});

serialQueue.add(function() {
     throw new Error('error that is not caught');
});

My thought is that the first one works because the _dequeue is directly in the try/catch. However on subsequent calls when the _dequeue is called from the then/reject the scope changes and it's not in the try/catch block anymore.

I was going to take a stab at a PR, but not sure the best way of handling it or if it's even possible without changing the interface.

Feature request: wait for capacity to free up

I would like to add items to the queue, and if the buffer is full, wait for a spot to open up.

The current workaround would look something like:

while(queue.getQueueLength() >= maxQueued) {
  await Bluebird.delay(100);
}
queue.add(item);

However, if the feature were part of the library it could be more efficient by adding the item as soon as a currently running item finishes.

Adding git repo link

Would be nice to have a link to the git repo on the npm page since i had to pass through another of you npm modules to find it.

Callback for empty queue?

I'm currently trying to check a list of ~140 URLs to make sure I get a status code of 200/OK, and am trying to use promise-queue.

I'm finding that after the queue drains, the thread kind of hangs, presumably waiting for more things to get into the queue.

Is there a way to check for queue.empty and call a callback or something? or some equivalent to Promise.all()?
Currently I just do if (queue.getQueueLength() === 0) process.exit(0); which feels like a pretty huge foot gun.

tplink-connection leaks promises in Queue object

this.on('timeout', () => {
  this.log.debug(
    `TplinkConnection(${this.description}): timeout()`,
    this.host,
    this.port
  );
  this.queue.add(async () => {
    this.close();
  });
});

The promise is never triggered. So, after every timeout, a promise will be leaked in the Queue object. Note, the current close function only performs a log statement, so the actual need for a promise in the current codebase.

I discovered this on a device that I think has a dubious network connection (HS300PowerStrip) and numerous children. I did see a couple of tplink-connection objects in memory tied to that IP address, but that may have just been for the children.

Queue Finished Event

Would be nice if there was a simple way to subscribe to an event that fired when the queue becomes empty, without the consumer needing to look at queue lengths.

Ownership transfer

Now it's in org https://github.com/promise-queue/promise-queue
@Crowes @AndersDJohnson would you be able to maintain this repo, keeping code quality one a good level as well as backwards compatibility?
I don't want to abandon this project as I am making use of it as well as many other people (2,348 downloads in the last day). Unfortunately I don't have much time for open-source these days.

What would be great to make:

  • Typescript
    ** worst case ES6
    ** without async function preferable (regenerator takes some space), it's discussable
  • Transpilation using Webpack
  • Upgrade/change test runner and update unit test
  • Upgrade code coverage lib
  • Keep code coverage on 100%
  • Keep backwards compatibility

Your live example not showing the real time status of the queue

// origin
$('button').click(function () {
    queue.add(processSomethingHeavy)
    .then(function ($loading) {
        status();
        $loading.remove();
    }, function (err) {
        $('<div>' + err + '</div>').appendTo('pre');
    });
    status();
});
// modified
$('button').click(function () {
    queue.add(processSomethingHeavy)
    .then(function ($loading) {
        $loading.remove();
    }, function (err) {
        $('<div>' + err + '</div>').appendTo('pre');
    });
});
setInterval(status, 50)

Documenting pendingPromises

I'd like to use the pendingPromises property but it is not documented so i'm wondering if you'll accept to add it on the README in order to make it part of the public API.

Feel free to ask me a PR since this issue and the previous one are for my convenience ;).

Feature Request: find()

Hi,

I have an application where there may be duplicate event/data that are generated and the duplicates shouldn't be queued. It doesn't look like there is a way to examine the promiseGenerator in the queue to see if this is the case, so I implemented something myself (see below). Then I implement a find() function to search the queue before adding. Is there a better way to do this or can this be added to a future version of promise-queue? Thanks, Bob Lund.

Queue.prototype.add = function (promiseGenerator, event, data) { //added event and data
.
.
.
// Add to queue
self.queue.push({
promiseGenerator: promiseGenerator,
resolve: resolve,
reject: reject,
notify: notify || noop,
event: event, //added
data: data //added
});

queue doesn't delay steps

In your live example, if I change the queue max size to 5 and click repeatedly, my steps execute in parallel, rather than sequentially. Am I wrong to assume that's the point of using promise-queue is to delay subsequent steps until the previous step completes?

Here's what I mean:
http://c.hlp.sc/3C0V220S0K11

Feature request: wait for all items in queue to finish

When running a script that runs jobs in parallel, it would be nice to have a promise we could wait on that resolves when all items in the queue are complete.

The current workaround would look like this:

while(queue.getQueueLength() + queue.getPendingLength() > 0) await Bluebird.delay(100);

If the feature were built into the library a more elegant solution should be possible.

Interval question

Hey everyone!

Here's what I'm trying to accomplish.

I need a queue to run 5 concurrent tasks. Let's say I add 10. I'd like to see 5 tasks running, a delay, another 5.

Currently the lib doesn't have such option, does it?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.