master-cluster
Advanced tools
Comparing version 0.2.0 to 0.3.0
'use strict'; | ||
var assert = require('assert'); | ||
var cluster = require('cluster'); | ||
var http = require('http'); | ||
var os = require('os'); | ||
var debug = require('debug')('master-cluster'); | ||
var reloader = require('./reloader'); | ||
var setup = {}; | ||
var noop = function () {} | ||
function start (options) { | ||
if (! cluster.isMaster) throw new Error('Start can only be run on master!'); | ||
assert(cluster.isMaster, 'Start can only be run on master!'); | ||
options = options || {}; | ||
if (options.isCluster === false) { | ||
setup = options; | ||
if (options.exec) require(options.exec); | ||
assert(options.exec, 'exec option must be specified to run in non-cluster mode'); | ||
require(options.exec); | ||
return; | ||
} | ||
if (! options.size) options.size = require('os').cpus().length; | ||
if (! options.size) options.size = os.cpus().length; | ||
setup.logger = options.logger; | ||
@@ -21,3 +28,3 @@ | ||
var counter = 0; | ||
var counterReloadWorkerFails = 0; | ||
var reload = options.reload || options.reload === false ? options.reload : /^dev/.test(process.env.NODE_ENV); | ||
@@ -27,6 +34,2 @@ | ||
reloader.reload(options); | ||
cluster.reset = function () { | ||
eachCluster(options.size, fork); | ||
counter = 0; | ||
} | ||
} | ||
@@ -36,2 +39,6 @@ | ||
cluster.on('fork', function (worker) { | ||
debug('Worker forked, id %d', worker.id); | ||
}); | ||
cluster.on('disconnect', function (worker) { | ||
@@ -43,11 +50,14 @@ debug('Worker %d with pid %s disconnected', worker.id, worker.process.pid); | ||
} | ||
if (counter > options.size * 3) { | ||
if (counterReloadWorkerFails > options.size * 3) { | ||
logError('Application is crashing. Waiting for file change.'); | ||
return; | ||
} | ||
if (counter === 0) | ||
if (counterReloadWorkerFails === 0) | ||
// reset `counterReloadWorkerFails` in reload mode | ||
// if there's no errors for more than 2 seconds | ||
setTimeout(function () { | ||
counter = 0; | ||
counterReloadWorkerFails = 0; | ||
}, 2000); | ||
counter++; | ||
counterReloadWorkerFails++; | ||
fork(); | ||
@@ -76,17 +86,14 @@ }); | ||
function run () { | ||
if (typeof setup.run === 'undefined') throw new Error('There is nothing to run!'); | ||
if (typeof setup.error === 'undefined') setup.error = function () {}; | ||
assert(cluster.isWorker, 'run can be executed only inside worker process'); | ||
assert(typeof setup.run === 'function', 'There is nothing to run!'); | ||
var d = require('domain').create(), args = arguments; | ||
d.on('error', onWorkerError); | ||
for (var i = 0; i < arguments.length; i++) d.add(arguments[i]); | ||
d.run(function () { | ||
setup.run.apply(this, args); | ||
}); | ||
if (typeof setup.error === 'undefined') setup.error = noop; | ||
setup.run.apply(null, arguments); | ||
} | ||
function createHttpServer (handler, port, onShutdown) { | ||
var http = require('http'); | ||
function createHttpServer (handler, port, onShutdown, onListening) { | ||
setFnHandlers (handler, onShutdown); | ||
return http.createServer(run).listen(port); | ||
if (!onListening) onListening = noop; | ||
return http.createServer(run).listen(port, onListening); | ||
} | ||
@@ -96,3 +103,3 @@ | ||
setup.run = runFn; | ||
setup.error = errorFn || function () {}; | ||
setup.error = errorFn || noop; | ||
return this; | ||
@@ -99,0 +106,0 @@ } |
@@ -5,3 +5,3 @@ { | ||
"description": "Facilitate using cluster and domain modules, live reload application in development mode on code change.", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"dependencies": { | ||
@@ -8,0 +8,0 @@ "debug": "^2.0.0", |
@@ -5,4 +5,3 @@ # master-cluster | ||
in any project. I created this module as I use the cluster module in pretty much all my projects and wanted to | ||
remove the boilerplate code. It implements node.js core [domain](http://nodejs.org/api/domain.html) module | ||
for correct exception handling. It also provides hot reloading of files on the worker in development mode | ||
remove the boilerplate code. It also provides hot reloading of files on the worker in development mode | ||
so that workers are restarted when code is changed. | ||
@@ -28,4 +27,3 @@ | ||
// create the server and pass MC run handler | ||
// each request will be wrap in a domain for exception handling | ||
// so that workers are restarted automatically on crash | ||
// workers are restarted automatically on crash | ||
var server = http.createServer(MC.run); | ||
@@ -57,3 +55,5 @@ server.listen(3000, function () { | ||
MC.createHttpServer(app.index, 3000, shutdown); | ||
MC.createHttpServer(app.index, 3000, shutdown, function () { | ||
console.log("Listening on %d", 3000); | ||
}); | ||
@@ -85,6 +85,7 @@ function shutdown () { | ||
- `exec`: the code to run on the cluster master | ||
- `exec`: file path to worker file (see `exec` option of [cluster.setupMaster](https://nodejs.org/api/cluster.html#cluster_cluster_setupmaster_settings)) | ||
- `size`: the number of workers to start, default is `require("os").cpus().length` | ||
- `reload`: `boolean`, default is `false` except when `process.env.NODE_ENV == 'dev'` | ||
- `reload`: `boolean`, default is `false` except when `/^dev/.test(process.env.NODE_ENV)` | ||
- `logger`: optional logger for errors (must implement `error` method) | ||
- `isCluster`: pass `false` to disable `cluster` and run master-only process. Setting `exec` is required in this case | ||
@@ -95,2 +96,3 @@ Reloader specific options: | ||
- `extensions`: file extensions to watch for and reload on change, default to `js` | ||
- `path`: path to watch for change, default to current directory (`.`) | ||
@@ -105,10 +107,10 @@ Worker options: | ||
- `start (options)`: start the master with cluster options | ||
- `run ()`: worker http handler that runs the request wrapped in the domain error handling | ||
- `setFnHandlers (runFn, errorFn)`: set the run and error handlers for the domain module | ||
- `run ()`: worker http handler that runs the request | ||
- `setFnHandlers (runFn, errorFn)`: set the run and error handlers | ||
- `setOptions (options)`: set the options for the workers (logger and kill timeout) | ||
- `createHttpServer (handler, port, onShutdown)`: create the http server and setup the run and error handlers for the domain module | ||
- `createHttpServer (handler, port, onShutdown, onListening)`: create the http server and setup the run and error handlers | ||
### Miscellaneous | ||
- `cluster`: expose the exported cluster module | ||
- `cluster`: expose node.js [cluster](https://nodejs.org/api/cluster.html) module | ||
@@ -115,0 +117,0 @@ # Disclaimer |
13520
221
123