0

I have a node app that uses node canvas to generate a dot plot graph from a file.

I'm having a problem with requests blocking each other. These requests involve CPU heavy looping through of large arrays (close to 1 million in length).

For example, I have one request which does some analysis on the file. This involves looping through an array with a length of 800k+ and calculating the mean value.

app.get('/api/get/statistics', function(req, res) {

    // Promise here which gets files and loops through and calculates mean

});

Another request loops through the same array and creates a graph and returns to the UI.

app.get('/api/canvas', function(req, res) {

    // creates the graph

});

On their own, the first request takes about 40 seconds and the second about 13 seconds. But when I make the requests at the same time, the second request will take about 53 seconds (and sometimes times out) as it's being queued.

Is there a way around this? I was thinking I could use child processes, perhaps with this package. But it seems like from this question it might not be possible with seperate HTTP requests.

Note: I don't want to do these in the same request. Most of the time I'm firing off multiple requests to the '/api/canvas' endpoint to create different graphs. So I'm basically wondering is it possible to execute these CPU heavy requests at the same time?

6
  • You should redesign your architecture. I had to do something similar and the best solution for me is to just trigger the start of a job via ajax that then runs on the server. On the client side, you can see the status of this job and you're notified when the job is ready (via WebSockets). I also moved the heavy work into a separate node thread that runs parallel. Commented May 18, 2017 at 8:21
  • Off topic. Calculating avg for 1M records shouldn't be anywhere close to 40 seconds. It should be like 40ms on modern CPU jsfiddle.net/xttcro2f/1 Commented May 18, 2017 at 8:52
  • @YuryTarabanko: He's making 1M HTTP requests, not merely adding numbers. I don't know about you but my network can't really do that in 40ms Commented May 18, 2017 at 9:15
  • @slebetman 1M HTTP requests? Where do you get this? OP says he is looping through array with values calculating avg " I have one request ... This involves looping through an array with a length of 800k+ and calculating the mean value" Which is "merely adding numbers". Commented May 18, 2017 at 9:36
  • @YuryTarabanko Yes, one request. Its a bit more complex - its a 2D array. 2 points represent x,y on a graph. I then check if these are within a polygon or multiple polygons, getting mean for each polygon & combination of polygons Commented May 18, 2017 at 9:57

1 Answer 1

1

Dispatch the calculation to another process to make it asynchronous and prevent it from blocking the NodeJS thread as it does now.

One way is to use child_process.fork and communicate with it via child.send. If the child process is not a NodeJS process, comminicate via its stdin and stdout for requests and responses correspondingly, stderr for errors.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.