Mastering Node.js(Second Edition)
上QQ阅读APP看书,第一时间看更新

Child processes

A fundamental part of Node's design is to create or fork processes when parallelizing execution or scaling a system, as opposed to creating a thread pool, for instance. We will be using these child processes in various ways throughout this book. Right now, the focus will be on understanding how to handle communication events between child processes.

To create a child process, require Node's child_process module, and call the fork method. Pass the name of the program file the new process should execute:

let cp = require("child_process");
let child = cp.fork(__dirname + "/lovechild.js");

You can keep any number of subprocesses running with this method. On multicore machines, the operating system will distribute forked processes across the available hardware cores. Spreading Node processes across cores, even onto other machines, and managing IPC is one way to scale a Node application in a stable, understandable, and predictable way.

Extending the preceding example, we can now have the forking process (parent) send, and listen for, messages from the forked process (child). Here's the code for parent.js:

// parent.js
const cp = require("child_process");
let child = cp.fork(__dirname + "/lovechild.js");

child.on("message", (m) => {
console.log("Child said: ", m); // Parent got a message up from our child
});
child.send("I love you"); // Send a message down to our child

The following is the output for parent.js:

$ node parent.js
Parent said: I love you
Child said: I love you too
(then Ctrl+C to terminate both processes)

Alongside that file, make another one and name it lovechild.js.  The code of the child in here can listen for messages and send them back up:

// lovechild.js
process.on("message", (m) => {
console.log("Parent said: ", m); // Child got a message down from the parent
process.send("I love you too"); // Send a message up to our parent
});

Don't run lovechild.js yourself; --parent.js will do that for you with fork!

Running parent.js should fork a child process and send that child a message. The child should respond in kind:

Parent said:  I love you
Child said: I love you too

With parent.js running, check your operating system's task manager. There will be two Node processes, not one, as there were with preceeding examples.

Another very powerful idea is to pass a network server an object to a child. This technique allows multiple processes, including the parent, to share the responsibility for servicing connection requests, spreading load across cores.

For example, the following program will start a network server, fork a child process, and pass the server reference from the parent down to the child:

// net-parent.js
const path = require('path');
let child = require("child_process").fork(path.join(__dirname, "net-child.js"));
let server = require("net").createServer();

server.on("connection", (socket) => {
socket.end("Parent handled connection");
});

server.listen(8080, () => {
child.send("Parent passing down server", server);
});

In addition to passing a message to a child process as the first argument to send, the preceding code also sends the server handle to itself as a second argument. Our child server can now help out with the family's service business:

// net-child.js
process.on("message", function(message, server) {
console.log(message);
server.on("connection", function(socket) {
socket.end("Child handled connection");
});
});

This child process should print out the sent message to your console, and begin listening for connections, sharing the sent server handle.

Repeatedly connecting to this server at localhost:8080 will result in either child-handled connection or parent-handled connection being displayed; two separate processes are balancing the server load. This technique, when combined with the simple inter-process messaging protocol discussed previously, demonstrates how Ryan Dahl's creation succeeds in providing an easy way to build scalable network programs.

We've connected two nodes with just a few lines of code.

We will discuss Node's new cluster module, which expands and simplifies the previously discussed technique in Chapter 7, Using Multiple Processes. If you are interested in how server handles are shared, visit the cluster documentation: https://nodejs.org/dist/latest-v9.x/docs/api/cluster.html