diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index 6e02f484860..11184a5799c 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -4,14 +4,22 @@ A single instance of Node runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node processes to handle the load. -By starting node with the `cluster` argument, Node will detect the number of -CPUs on the machine and start that many processes. For example suppose we -had a simple HTTP server in server.js: +The cluster module allows you to easily create a network of processes all +which share server ports. - require('http').createServer(function(req, res) { + var cluster = require('cluster'); + var http = require('http'); + + if (!cluster.isWorker()) { + // Start the master process, fork workers. + cluster.startMaster({ workers: 2 }); + } else { + // Worker processes have a http server. + http.Server(function(req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }).listen(8000); + } If we start it like this diff --git a/lib/cluster.js b/lib/cluster.js index 75bcfa560a2..38229c99869 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -48,22 +48,47 @@ var queryIds = 0; var queryCallbacks = {}; -exports.start = function() { + +// Used to check if this process is a worker or not. +// Returns boolean. +exports.isWorker = function() { + return 'NODE_WORKER_ID' in process.env; +}; + + +// Call this from the master process. It will start child workers. +// +// options.workerFilename +// Specifies the script to execute for the child processes. Default is +// process.argv[1] +// +// options.args +// Specifies program arguments for the workers. The Default is +// process.argv.slice(2) +// +// options.workers +// The number of workers to start. Defaults to os.cpus().length. +exports.startMaster = function(options) { amMaster = true; - if (process.argv.length < 1) { - console.error('Usage: node cluster script.js'); - process.exit(1); + if (!options) { + options = {}; } - var args = process.argv.slice(2); - var scriptFilename = args.shift(); + if (!options.workerFilename) { + options.workerFilename = process.argv[1]; + } - var cpus = require('os').cpus().length; - console.error("Detected " + cpus + " cpus"); + if (!options.args) { + options.args = process.argv.slice(2); + } - for (var i = 0; i < cpus; i++) { - forkWorker(scriptFilename, args); + if (!options.workers) { + options.workers = require('os').cpus().length; + } + + for (var i = 0; i < options.workers; i++) { + forkWorker(options.workerFilename, options.args); } process.on('uncaughtException', function(e) { @@ -118,7 +143,7 @@ function handleWorkerMessage(worker, message) { } -function forkWorker(scriptFilename, args) { +function forkWorker(workerFilename, args) { var id = ++ids; var envCopy = {}; @@ -128,7 +153,7 @@ function forkWorker(scriptFilename, args) { envCopy['NODE_WORKER_ID'] = id; - var worker = fork(scriptFilename, args, { + var worker = fork(workerFilename, args, { env: envCopy }); diff --git a/src/node.cc b/src/node.cc index f846115c729..377fbe64ab2 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2261,7 +2261,6 @@ static void ParseDebugOpt(const char* arg) { static void PrintHelp() { printf("Usage: node [options] [ -e script | script.js ] [arguments] \n" " node debug script.js [arguments] \n" - " node cluster script.js [arguments] \n" "\n" "Options:\n" " -v, --version print node's version\n" diff --git a/src/node.js b/src/node.js index 863cf1693a4..520ddae5e98 100644 --- a/src/node.js +++ b/src/node.js @@ -68,10 +68,6 @@ var d = NativeModule.require('_debugger'); d.start(); - } else if (process.argv[1] == 'cluster') { - var cluster = NativeModule.require('cluster'); - cluster.start(); - } else if (process._eval != null) { // User passed '-e' or '--eval' arguments to Node. var Module = NativeModule.require('module');