Save the JavaScript promise for future use

I am working on Node.js to create server side RESTApi. Node works great when I tested it myself. But when it does, it can still run into overflow problems. When there are many requests, say there are more than 5 spawn processes running at the same time, each process takes longer, basically slows everything down.

My idea is to check if the current process is below a certain limit (for example, the limit is up to 3 processes at a time), if it exceeds the limit, I store the requests in an array and whenever the current processes are below the limit, I use .shift (). to pull out the oldest one from the array and process it.

However, when it comes to Promises, it gets tricky as I don't know if we can save the Promise to an array or not, or if I should just let the process pause for seconds, which I don't think is a good idea.

What is the normal way if you want to keep a promise and return the promise to the customer in the future?

Sorry if I didn't say this is clear. Here's a quick summary of my concerns: 1. Can we keep the promise for future use? 2. Do we store them in arrays? 3. Should I use other methods to fulfill the promise, for example using sleep () or just a while loop to wait until the process continues?

Thank!

+3


source to share


2 answers


it is said that there are more than 5 spawn processes running at the same time, each process takes longer, basically slows everything down.

In the real world, deployment - this way you won't handle CPU intensive tasks with child tasks - you would use a reasonable parallel data structure (like a queue to mqtt or a database) and distribute work to the workers you deploy, then dispatch it back to the server.

The reason is that the server can always go down - and you want to protect against partial work.

My idea is to check if the current process is below a certain limit (for example, the limit is up to 3 processes at a time), if it exceeds the limit, I store the requests in an array and whenever the current processes are below the limit, I use .shift (). to pull out the oldest one from the array and process it.

Here is the code that does this, I ask you to read the first point and not use this code in production, but instead restrict this when deploying (for example, if you are using AWS to limit the scale to 3 instances):



// lifted from my bluebird-api project
function throttle(fn, concurrency = 20, Promise) {
    // create an array of workers as resolved promises
    const workers = Array(concurrency).fill(Promise.resolve());
    const work = []; // pending work
    return function (...args) {
        // when there is work, pull the next worker
        const worker = workers.pop();
        if (worker === undefined) { // if there is no pending worker
            let resolve, reject;
            // store the promise for the result
            const promise = new Promise((res, rej) => {
                resolve = res; 
                reject = rej;
            });
            // and add it to the queue
            work.unshift({ args, resolve, reject, promise });
            return promise;
        }
        // after the worker is ready, call the function
        worker = worker.then(() => (fn(...args), null));
        worker.then(function pump() {
            if (work.length) { // after you're ready
                const {resolve, reject, args} = work.pop();
                // continue draining the queue
                worker = worker.then(() => fn(...args)).then(resolve, reject).then(pump);
            } else { // or declare ready
                workers.push(worker);
            }
            return null;
        });
        return worker;
    }
} 

      

Code stripped from bluebird-api , which is still WIP.

What is the normal way if you want to keep a promise and return the promise to the customer in the future?

Yes, this is a fully supported case - and it does not flow in memory and is safe (in the modern implementation of the promise). Although again - this is an XY issue - you shouldn't distribute this work on a Node.

When you implement the right solution (queuing and offloading to different services), you can create a promises queue where you return the promise and resolve it later when the queue is ready.

+2


source


  • Can a promise be kept for future use? 2. Do we store them in arrays?

You can store the Promises in an array, which is part of the beauty of the promises, so they don't need to be evaluated until needed.

  1. Should I use other methods to fulfill the promise, such as using sleep () or just a while loop to wait until the process continues?


Nothing wrong with using sleep. Don't cycle that is ineffective.

EDIT

@Bergi says in the comments that even in Promise sleep

it shouldn't be used either.

+1


source







All Articles