2

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.

tru7
  • 6,348
  • 5
  • 35
  • 59
  • You should keep reference to them in an array, that way you can use promise.all to handle when they are all finished. – mattdevio Dec 30 '17 at 09:31
  • Don't count promises (or even promises globally). Count the particular insertions that you are concerned about. – Bergi Dec 30 '17 at 13:11

2 Answers2

3

...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;
    });
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks, finally it didn't grow that much (never reached 20 outstanding). One question, I don't understand your construct p.catch(e => e).then().... what does that catch there? (although it works) – tru7 Dec 30 '17 at 11:04
  • 1
    @Joan: That's a "poor man's `finally`". :-) The `catch` turns a rejection into a resolution, so our subsequent `then` handler will always get called (whether the project rejects or resolves). (That's also why we return `p` instead of returning the result of calling `then`, because we don't want to mess up rejection handling on the promise as a whole.) – T.J. Crowder Dec 30 '17 at 11:35
0

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())
HMR
  • 37,593
  • 24
  • 91
  • 160