tru7
tru7

Reputation: 7222

node.js how many promises pending (globally)

Is there a way to tell how many promises are pending in the whole app?

I am feeding records in batch mode to a database (with sequelize). Each insertion is a promise, the rate of requests is higher than the resolves so the number of pending promises is increasing.

What is a good approach to this? awaiting each insertion seems less efficient but I suspect that letting the pending promises grow will collapse eventually.

So far I'd like to know how many promises are pending globally to analyze the rate of growth and study possible solutions or get some ideas here.

Upvotes: 2

Views: 2202

Answers (2)

HMR
HMR

Reputation: 39270

You could try to throttle active promises using this. I assume you do a Promise.all, how large is the array you pass to it?

TJ has a good answer but you should re throw the reject value

var trackPromise = (
  outstanding => {
    return {
      add:p => {
        outstanding++;
        return p.then(x=>{
          outstanding--;
          return x;
        })
        .catch(
          err=>{
            outstanding--;
            return Promise.reject(err);
          }
        );
      },
      count:()=>outstanding  
    };
  }
)(0)

trackPromise.add(Promise.resolve(22))
.then(
  resolve=>console.log("resolved:",resolve),
  reject=>console.warn("rejected:",reject)
);
trackPromise.add(Promise.reject(0))
.then(
  resolve=>console.log("resolved:",resolve),
  reject=>console.warn("rejected:",reject)
);
console.log("active:",trackPromise.count())

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074475

...but I suspect that letting the pending promises grow will collapse eventually.

Only because you'll run out of memory or maybe because your sequelize connector reaches a point where it can't handle the outstanding number of requests. But yes, you want to avoid constantly increasing the number of outstanding requests.

There's nothing built-in to tell you this, but you can easily know how many of the relevant ones are outstanding by simply keeping track:

let outstanding = 0;
function track(p) {
    ++outstanding;
    p.catch(e => e).then(() => {
        --outstanding;
    });
    return p;
}

Then just wrap your sequelize calls in calls to track:

track(calltoSequelize(/*...*/)).then(/*...*/);

If you use a promises library with finally (or use the polyfill from the proposal), track can be:

let outstanding = 0;
function track(p) {
    ++outstanding;
    return p.finally(() => {
        --outstanding;
    });
}

Upvotes: 3

Related Questions