0

I have a node js application that has two GET requests, say for example - test and delay,

var express = require("express");
var app = new express();
app.use('/', express.Router());

app.get('/delay', function (req, res) {
    for (var i = 0; i < 500000; i = i + 0.0001) {
        let r = 'r';
    }
    res.json({ 'message' : 'delay message'});
})

app.get('/test', function (req, res) {
    res.json({ 'message': 'hello world' });
})

app.listen(1337);

The delay method executes and produces a delayed output, like after around 6-7 seconds, whereas the test method produces the output immediately.

But while testing in Postman, if i run delay method and before its completion if i run test, then the output of test does not appear until delay is completed. I get the output of test only after delay is completed.

How to make these two requests run parallely, independent of one another???

P.S: I have also tried router (express.Router()), but still it is the same.

Thanks!

2
  • i'm sorry then how can i make both run parallelly?? Commented Feb 28, 2018 at 11:23
  • because i have a lot of routes, and receive a lot of request, some of which may take some time to execute, so all the other request now have to wait until the completion of each route,, Commented Feb 28, 2018 at 11:24

4 Answers 4

3

The delay endpoint is blocking, it's an expensive loop hogging the single thread the server is running on. You will need to relinquish control of the thread to the global event loop so it's free to take on new requests, and schedule an event to happen at a later time. Typically you do that with setTimeout, or using some other asynchronous API that takes a callback:

app.get('/delay', function (req, res) {
    setTimeout(function () { res.json({ 'message' : 'delay message'}); }, 6000);
})

If you do have an expensive task that must run to completion, you need to look into threading or into moving that into a completely different process with which you communicate via sockets or something.

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

Comments

0

Your for loop takes too much time to execute and it is not an asynchronous code, its synchronous. However you can extract for block to another function which returns promise. In that way you can achieve asynchronicity in your code.

Comments

0

You can't. Node.js runs the event loop on a single thread. If you have blocking code, then it will block.

Avoid performing CPU intensive operations (like looping over and over while doing nothing important).

There are approaches you can take to mitigate this sort of issue (such as processing data in batches with setTimeout being used to let other events on the event queue run between batches) but the best approach for dealing with any given problem would depend on the real problem.

4 Comments

so then, if it is single threaded, then what is the best way to handle multiple routes?? i've written a web api application and now not more than 2-3 users can work simultaneously.. for ex., if an api to load a list is called which takes around 6-7 seconds, then another user calling a login route (which takes only few milliseconds) faces a delay on his response.. what is the best way to deal with this type of situation???
@sanatsathyan — As I said. It depends. Why does "loading a list" take so long?
because it fetches a huge data from SQL and performs operations and returns an output. i even tried child process but then node js started consuming alot of memory, gradually even increased upto 1GB,..so i'm slowly moving the code to C#, but still wanted to go for a last try...
Are you calling the database synchronously? Can you move the logic for those unspecified operations to SQL? Are you batch up the operations as mentioned in the last paragraph of the question? Can you speed things up with caching? Can you move the unspecified operations to an intermediary service and access it via a queuing system?
0

That's pretty much how Node.js works. It's a single-threaded event-loop, unlike other server implementations that operate on a thread-per-request basis which is perhaps what you're thinking of.

Generally, you don't want to lock up the main thread by performing a single, long cpu intensive action within the request. Instead, you'd likely hand that off to a worker or similar, like setTimeout.

Of course, you could have more Node.js instances and cluster them in some fashion, such that your two calls might be load-balanced to separate backend Node.js servers, but in your case it seems more likely that you just need to adopt a more async approach within your long-running method to free-up the main thread to service other calls.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.