Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js / express: respond immediately to client request and continue tasks in nextTick

I would like to separate server high consuming CPU task from user experience:

./main.js:

var express = require('express');
var Test = require('./resources/test');
var http = require('http');
var main = express();

main.set('port', process.env.PORT || 3000);
main.set('views', __dirname + '/views');
main.use(express.logger('dev'));
main.use(express.bodyParser());
main.use(main.router);

main.get('/resources/test/async', Test.testAsync);

main.configure('development', function() {
  main.use(express.errorHandler());
});

http.createServer(main).listen(main.get('port'), function(){
  console.log('Express server app listening on port ' + main.get('port'));
});

./resources/test.js:

function Test() {}
module.exports = Test;

Test.testAsync = function(req, res) {
  res.send(200, "Hello world, this should be sent inmediately");
  process.nextTick(function() {
    console.log("Simulating large task");
    for (var j = 0; j < 1000000000; j++) {
      // Simulate large loop
    }
    console.log("phhhew!! Finished!");
  });
};

When requesting "localhost:3000/resources/test/async" I would expect the browser rendering "Hello world, this should be sent inmediately" really fast and node.js to continue processing, and after a while in console appearing "finished" message.

Instead, browser keeps waiting until node.js finishes large task and then renders the content. I've tried with res.set({ 'Connection': 'close' }); and also res.end(); but nothing works as expected. I've also googled with no luck.

How should it be to send the response to client immediately and server continue with tasks?

EDIT

posted fork method in solution

like image 258
Miquel Avatar asked Jan 22 '14 16:01

Miquel


1 Answers

Try waiting instead of hogging the CPU:

res.send("Hello world, this should be sent inmediately");
console.log("Response sent.");
setTimeout(function() {
  console.log("After-response code running!");
}, 3000);

node.js is single-threaded. If you lock up the CPU with a busy loop, the whole thing grinds to a halt until that is done.

like image 81
Peter Lyons Avatar answered Sep 19 '22 07:09

Peter Lyons