Question

I am implementing a very basic website using nodejs, and expressjs framework. The idea is that the user enters the website, click on a button that will trigger a cpu-intensive task in the server, and get a message on the browser upon the completion of the task.

The confusing part for me is how to accomplish this task for each user without blocking the event-loop, thus, no user has to wait for another to finish. Also, how to use a new instance of the used resources(objects, variables..) for each user.

After playing and reading around, I have come across child-process. Basically, I thought of forking a new child_process for each user so that whatever the time the sorting takes, it won't block my event-loop. However, I am still not sure if this is the best thing to do for such a scenario.

Now, I have done what I wanted to but with only single user, however when trying to start another user, things become messy and variables are shared. I know that I should not use global variables declared in the module, but what could be another way to make variables shared among functions within a single module yet they are different for each user!?

I know that the question may sound very basic, but I kinda miss the idea of how does node js serve different users with new variables, objects that are associated with each individual user.

In short, my questions are: 1- how does node serve multiple users simultaneously? 2- when and how should I resort to forking or executing a new child-process under the hood, and is it for each user or based on my # cores in cpu 3- how to separate resources in my application for each user such that each user has his own counters, emails and other objects and variables. 4- when do I need or I have to kill my child process.

Thanks in advance.

CODE:

var cp = require('child_process');
var child= cp.fork('./routes/mysort-module');

exports.user=function(req,res){
    // child = new cp.fork('./routes/mysort-module'); // Should I make new child for each user?
    child.on('message',function(m){ res.send('DONE');}
    child.send('START PROCESS'); // Forking a cpu-intensive task in mysort-module.js

}

IN MY SORTING MODULE:

var variables = require(...);
//GLOBAL VARIABLES to be shared among different functions in this module 
process.on('message',function(m){
    //sort cpu-intensive task
    process.send('DONE');
});
// OTHER FUNCTIONS in THE MODULE that make use of global variables.
Was it helpful?

Solution

You should try to split up your question. However, I hope this answers it.

Question 1: A global variable is not limited to request scope. That's a part of Node's definition for a global and it doesn't make sense to enforce this somehow. You shouldn't use globals at all.

The request scope is given by the HTTP module:

http.createServer(function(req, res) {
  var a = 1;
  // req, res, and a are in request scope for your user-associated response
}); 

Eliminating globals shouldn't be that hard: If module A and B share a global G and module C calls A.doThis() and B.doThat(), change C to call A.doThis(G) and B.doThat(G) instead. Do this for all occurrences of G and reduce its scope to local or request.

Additionally, have a look for "Sessions", if you need a scope coverig multiple requests from one client.

Question 2: Start the child process inside the request handler:

exports.user = function(req,res){
  child = new cp.fork('./routes/mysort-module');

Question 3: See question 1?

Question 4: After the process returned the calculated results.

process.on('DONE', function(result) {
  process.exit();
  // go on and send result to the client somehow...
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top