clusterflock
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -33,2 +33,13 @@ var cluster = require('cluster'), | ||
process.on('SIGTTIN', function() { | ||
logfmt.log({ evt: 'received TTIN, forking additional worker' }); | ||
cluster.fork(); | ||
}); | ||
process.on('SIGTTOU', function() { | ||
logfmt.log({ evt: 'received TTOU, removing worker' }); | ||
var worker = cluster.workers[Object.keys(cluster.workers)[0]]; | ||
worker.disconnect(); | ||
}); | ||
process.once('SIGINT', function() { | ||
@@ -35,0 +46,0 @@ logfmt.log({ evt: 'received SIGINT, immediately shutting down' }); |
{ | ||
"name": "clusterflock", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "a clustering http server for node", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -39,3 +39,20 @@ # clusterflock [![Build Status](https://travis-ci.org/jclem/clusterflock.png)](https://travis-ci.org/jclem/clusterflock) | ||
### Worker Re-forking | ||
When a worker disconnects, the master checks the value of its [`suicide`](http://nodejs.org/api/cluster.html#cluster_worker_suicide) attribute. If that value is true, master does nothing. If that value is not true (i.e. the worker died/was killed unintentionally), the master forks a new worker. | ||
## Options | ||
The `clusterflock` function accepts an options object: | ||
```javascript | ||
var clusterflock = require('clusterflock'), | ||
app = require('./lib/app'); | ||
clusterflock(app, { | ||
numWorkers: 1, | ||
port : 3000, | ||
timeout : 5000 | ||
}); | ||
``` | ||
@@ -48,2 +65,14 @@ Name | Type(s) | Default | Description | ||
## Signals | ||
clusterflock responds to signals. [heroku, for example](https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm), sends `SIGTERM` to stop and restart dynos, which will cause clusterflock to initiate a graceful shutdown. `SIGINT`, on the other hand, will force clusterflock to shut down immediately. | ||
Signal | Behavior | ||
--------- | -------------------------------------------------------- | ||
`SIGTTIN` | Fork an additonal worker | ||
`SIGTTOU` | Disconnect the least-recently forked worker | ||
`SIGINT` | Kill master process (and therefore workers) immediately. | ||
`SIGTERM` | Forward myself `SIGQUIT`. | ||
`SIGQUIT` | Attempt a graceful shutdown (stop serving requests, serve remaining requests, and shut down). | ||
## Testing | ||
@@ -50,0 +79,0 @@ |
@@ -68,2 +68,33 @@ require('./spec-helper'); | ||
it('logs a fork on SIGTTIN', function() { | ||
master({}); | ||
spyOn(logfmt, 'log'); | ||
process.emit('SIGTTIN'); | ||
expect(logfmt.log).toHaveBeenCalledWith({ evt: 'received TTIN, forking additional worker' }); | ||
}); | ||
it('forks a new worker on SIGTTIN', function() { | ||
master({}); | ||
process.emit('SIGTTIN'); | ||
expect(cluster.fork).toHaveBeenCalled(); | ||
}); | ||
it('disconnects a worker on SIGTTOU', function() { | ||
var spy = jasmine.createSpy(); | ||
cluster.workers = { 1: { disconnect: spy } }; | ||
master({}); | ||
spyOn(logfmt, 'log'); | ||
process.emit('SIGTTOU'); | ||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
it('logs a disconnect on SIGTTOU', function() { | ||
var spy = jasmine.createSpy(); | ||
cluster.workers = { 1: { disconnect: spy } }; | ||
master({}); | ||
spyOn(logfmt, 'log'); | ||
process.emit('SIGTTOU'); | ||
expect(logfmt.log).toHaveBeenCalledWith({ evt: 'received TTOU, removing worker' }); | ||
}); | ||
it('traps and logs SIGINT once', function() { | ||
@@ -70,0 +101,0 @@ master({}); |
20236
454
95