LearnBoost/up — pull request #37 by gjohnson (2012-06-30 18:32:45+00:00)
Title: Working Directory, Signals, Respawn and Internals.

Sorry for the single pull request, committed too much at once...

### Working Directory

This adds the ability for the CLI to accept the option `-d/--directory` to change the location of process.chdir.

### Signals

This adds the following signals for the CLI to bind to. Right now they are bound no matter what, but perhaps there should be an option `-s/--signals` for opting out.

- `SIGTTIN`: Spawn a new worker to the round.
- `SIGTTOU`: Remove a worker from the round.
- `SIGTERM`: Hard shutdown of master and workers.
- `SIGQUIT`: Gracefully shutdown workers and the master.
- `SIGUSR1`: Gracefully shutdown workers but keep the master up.

### Respawning

This adds the feature of spawning a new worker after an existing one exits. There are two conditions that must be satisfied in order for this to happen.

- The worker needs to have exited unexpectedly (e.g. worker.exitCode === 1). This is accomplished simply by checking the `exit` from exit event emitted by a child_process.
- The worker needs to have an uptime greater than the `uptimeThreshold` which can be set through the CLI options via `-u/--uptime`.

### API and Internal Changes

To add some of the features above, I changed `UpServer` and `Worker` a good bit. Previously `UpServer#reload` was the only hook into spawning and shutting down workers. I have added:

- UpServer#shutdownWorkers();
- UpSerever#shutdown();
- UpServer#exit();
- UpServer#removeWorker();
- Worker#exit();

`UpServer.reload()` is alot slimmer now, these changes may be debatable. Before, [if there was a workerTimeout set](https://github.com/LearnBoost/up/blob/master/lib/up.js#L120), new workers were spawned and upon the first worker being spawned, the old workers were `shutdown`. However, [if there was no workerTimeout set](https://github.com/LearnBoost/up/blob/master/lib/up.js#L140), the workers were shutdown and after the last worker died, the new workers were spawned. Unless I was looking at it wrong, it did not make a whole lot of sense, so I [trimmed it down](https://github.com/gjohnson/up/blob/shutdown_reload/lib/up.js#L190) to only the first case.

To handle the [re-spawning](https://github.com/gjohnson/up/blob/shutdown_reload/lib/up.js#L119) without spinning into a cycical disaster, I simply bind to the `terminate` event in `UpServer` ctor. If the worker `exitCode` (which is set via `child_process.on('exit')`) is *1*, we check the `uptime` of the worker against the `uptimeThreshold`. If all is good, we respawn.