Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

node/server: added experimental support for cluster.js

  • Loading branch information...
commit 8bfe7d91eb181b68deb3ead22e5171396f51b52d 1 parent 118e105
Jerome Etienne authored

Showing 74 changed files with 4,630 additions and 1 deletion. Show diff stats Hide diff stats

  1. +15 0 node/server/cluster.js
  2. BIN  node/server/node_modules/cluster/._History.md
  3. BIN  node/server/node_modules/cluster/._Readme.md
  4. BIN  node/server/node_modules/cluster/._package.json
  5. BIN  node/server/node_modules/cluster/._test.js
  6. +3 0  node/server/node_modules/cluster/.gitignore
  7. +3 0  node/server/node_modules/cluster/.gitmodules
  8. +6 0 node/server/node_modules/cluster/.npmignore
  9. +112 0 node/server/node_modules/cluster/History.md
  10. +22 0 node/server/node_modules/cluster/LICENSE
  11. +8 0 node/server/node_modules/cluster/Makefile
  12. +98 0 node/server/node_modules/cluster/Readme.md
  13. BIN  node/server/node_modules/cluster/docs/._api.md
  14. BIN  node/server/node_modules/cluster/docs/._cli.md
  15. BIN  node/server/node_modules/cluster/docs/._debug.md
  16. BIN  node/server/node_modules/cluster/docs/._logger.md
  17. BIN  node/server/node_modules/cluster/docs/._pidfiles.md
  18. BIN  node/server/node_modules/cluster/docs/._reload.md
  19. BIN  node/server/node_modules/cluster/docs/._repl.md
  20. BIN  node/server/node_modules/cluster/docs/._stats.md
  21. +198 0 node/server/node_modules/cluster/docs/api.md
  22. +59 0 node/server/node_modules/cluster/docs/cli.md
  23. +27 0 node/server/node_modules/cluster/docs/debug.md
  24. +33 0 node/server/node_modules/cluster/docs/logger.md
  25. +41 0 node/server/node_modules/cluster/docs/pidfiles.md
  26. +39 0 node/server/node_modules/cluster/docs/reload.md
  27. +164 0 node/server/node_modules/cluster/docs/repl.md
  28. +45 0 node/server/node_modules/cluster/docs/stats.md
  29. +2 0  node/server/node_modules/cluster/index.js
  30. BIN  node/server/node_modules/cluster/lib/._cluster.js
  31. BIN  node/server/node_modules/cluster/lib/._master.js
  32. BIN  node/server/node_modules/cluster/lib/._worker.js
  33. +48 0 node/server/node_modules/cluster/lib/cluster.js
  34. +755 0 node/server/node_modules/cluster/lib/master.js
  35. +53 0 node/server/node_modules/cluster/lib/mixins/receiver.js
  36. +214 0 node/server/node_modules/cluster/lib/plugins/cli.js
  37. +108 0 node/server/node_modules/cluster/lib/plugins/debug.js
  38. +146 0 node/server/node_modules/cluster/lib/plugins/logger.js
  39. +64 0 node/server/node_modules/cluster/lib/plugins/pidfiles.js
  40. +120 0 node/server/node_modules/cluster/lib/plugins/reload.js
  41. +189 0 node/server/node_modules/cluster/lib/plugins/repl.js
  42. +113 0 node/server/node_modules/cluster/lib/plugins/stats.js
  43. +51 0 node/server/node_modules/cluster/lib/utils.js
  44. +199 0 node/server/node_modules/cluster/lib/worker.js
  45. BIN  node/server/node_modules/cluster/node_modules/log/._History.md
  46. BIN  node/server/node_modules/cluster/node_modules/log/._Makefile
  47. BIN  node/server/node_modules/cluster/node_modules/log/._Readme.md
  48. BIN  node/server/node_modules/cluster/node_modules/log/._index.js
  49. BIN  node/server/node_modules/cluster/node_modules/log/._package.json
  50. +12 0 node/server/node_modules/cluster/node_modules/log/History.md
  51. +14 0 node/server/node_modules/cluster/node_modules/log/Makefile
  52. +95 0 node/server/node_modules/cluster/node_modules/log/Readme.md
  53. BIN  node/server/node_modules/cluster/node_modules/log/examples/._file.js
  54. BIN  node/server/node_modules/cluster/node_modules/log/examples/._file.log
  55. BIN  node/server/node_modules/cluster/node_modules/log/examples/._reader.js
  56. BIN  node/server/node_modules/cluster/node_modules/log/examples/._stdout.js
  57. +18 0 node/server/node_modules/cluster/node_modules/log/examples/file.js
  58. +8 0 node/server/node_modules/cluster/node_modules/log/examples/file.log
  59. +15 0 node/server/node_modules/cluster/node_modules/log/examples/reader.js
  60. +16 0 node/server/node_modules/cluster/node_modules/log/examples/stdout.js
  61. +329 0 node/server/node_modules/cluster/node_modules/log/index.html
  62. +2 0  node/server/node_modules/cluster/node_modules/log/index.js
  63. +250 0 node/server/node_modules/cluster/node_modules/log/lib/log.js
  64. +1 0  node/server/node_modules/cluster/node_modules/log/package.json
  65. +1 0  node/server/node_modules/cluster/package.json
  66. +3 0  node/server/node_modules/cluster/support/should/.gitmodules
  67. +22 0 node/server/node_modules/cluster/support/should/History.md
  68. +6 0 node/server/node_modules/cluster/support/should/Makefile
  69. +248 0 node/server/node_modules/cluster/support/should/Readme.md
  70. +2 0  node/server/node_modules/cluster/support/should/index.js
  71. +91 0 node/server/node_modules/cluster/support/should/lib/eql.js
  72. +548 0 node/server/node_modules/cluster/support/should/lib/should.js
  73. +8 0 node/server/node_modules/cluster/support/should/package.json
  74. +6 1 node/server/server.js
15 node/server/cluster.js
... ... @@ -0,0 +1,15 @@
  1 +#!/usr/bin/env node
  2 +/**
  3 + * cluster script - https://github.com/learnboost/cluster
  4 +*/
  5 +
  6 +var cluster = require('cluster');
  7 +
  8 +cluster('./server.js')
  9 + .set('workers', 1) // only 1 workers
  10 + .use(cluster.logger('logs'))
  11 + .use(cluster.stats())
  12 + .use(cluster.pidfiles('pids'))
  13 + .use(cluster.cli())
  14 + .use(cluster.repl(8888))
  15 + .listen(8667);
BIN  node/server/node_modules/cluster/._History.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/._Readme.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/._package.json
Binary file not shown
BIN  node/server/node_modules/cluster/._test.js
Binary file not shown
3  node/server/node_modules/cluster/.gitignore
... ... @@ -0,0 +1,3 @@
  1 +testing
  2 +test.js
  3 +nohup.out
3  node/server/node_modules/cluster/.gitmodules
... ... @@ -0,0 +1,3 @@
  1 +[submodule "support/should"]
  2 + path = support/should
  3 + url = git://github.com/visionmedia/should.js.git
6 node/server/node_modules/cluster/.npmignore
... ... @@ -0,0 +1,6 @@
  1 +test
  2 +testing
  3 +examples
  4 +*.sock
  5 +*.pid
  6 +*.log
112 node/server/node_modules/cluster/History.md
Source Rendered
... ... @@ -0,0 +1,112 @@
  1 +
  2 +0.3.1 / 2011-02-28
  3 +==================
  4 +
  5 + * Added `cluster(filename)` support. Closes #45
  6 + This is highly recommended, view the API docs
  7 + on the site for more info.
  8 +
  9 +0.3.0 / 2011-02-28
  10 +==================
  11 +
  12 + * Added "worker exception" event. Closes #41
  13 + * Added `listen()` host dns resolution. Closes #35
  14 + * Added `pidfiles()` helper `master.pidof(name)`
  15 + * Added; `reload()` ignoring _node_modules_ and similar dirs. Closes #31
  16 + * Fixed master __PPID__ reference. Closes #38
  17 + * Fixed restart __SIGQUIT__ default
  18 + * Fixed; using `-g` for graceful shutdown instead of duplicate `-s`. Closes #39
  19 +
  20 +0.2.4 / 2011-02-25
  21 +==================
  22 +
  23 + * Added `Master#preventDefault` support to clean `cli()`.
  24 + Plugins can now tell master to "prevent its default behaviour", aka
  25 + listening for connections.
  26 +
  27 + * Fixed bug preventing consistent envs. Closes #37 [reported by sambarnes]
  28 + This caused `require.paths` to be altered.
  29 +
  30 + * Fixed; throw `pidfiles()` related errors, instead of ignoring
  31 +
  32 +0.2.3 / 2011-02-21
  33 +==================
  34 +
  35 + * Fixed `reload()` plugin; protect against cyclic restarts.
  36 +
  37 +0.2.2 / 2011-02-21
  38 +==================
  39 +
  40 + * Added __SIGCHLD__ trap to notify master of killed worker.
  41 + This means that master can now recover a child that
  42 + is __KILL__ed.
  43 + * Removed `Master#workerKilled()` call from worker
  44 +
  45 +0.2.1 / 2011-02-21
  46 +==================
  47 +
  48 + * Added `Master#do()`
  49 +
  50 +0.2.0 / 2011-02-21
  51 +==================
  52 +
  53 + * Added; maintaining worker count on __SIGCHLD__. Closes #28
  54 + * Added; defaulting `reload()` to the servers root dir
  55 + * Changed; `reload()` filtering out non-js files. Closes #30
  56 + * Removed __SIGHUP__ trap from worker
  57 +
  58 +0.1.1 / 2011-02-18
  59 +==================
  60 +
  61 + * Added vhost example
  62 + * Added restarts stat
  63 + * Added `'all'` env support, `in('all')` executing regardless
  64 + of the environment. Useful when `listen()`ing on the same port
  65 + regardless.
  66 +
  67 + * Changed; `working directory` setting defaulting to the script directory (POLS)
  68 +
  69 +0.1.0 / 2011-02-18
  70 +==================
  71 +
  72 + * Added TCP echo server example
  73 + * Added REPL `shutdown()` function
  74 + * Added REPL `stop()` function
  75 + * Added master spawning strategy
  76 + On restart, master now spawns a new master to accept
  77 + connections while the previous works (and master) finish
  78 + and die off.
  79 + * Added `Master#in()` for environment based usage. Closes #22
  80 + For example:
  81 + cluster(server)
  82 + .in('development')
  83 + .use(cluster.debug())
  84 + .use(cluster.repl())
  85 + .listen(3000)
  86 + .in('production')
  87 + .use(cluster.logger())
  88 + .listen(80);
  89 +
  90 + * Fixed some test race-conditions
  91 + * Fixed event leak. Closes #18
  92 +
  93 +0.0.4 / 2011-02-17
  94 +==================
  95 +
  96 + * Fixed `stats()` / `repl()` breakage when used with 0.2.x due to os mod. Closes #16
  97 + * Changed; close _REPL_ connections on shutdown
  98 +
  99 +0.0.3 / 2011-02-16
  100 +==================
  101 +
  102 + * Added log dependency to _package.json_. Closes #14
  103 +
  104 +0.0.2 / 2011-02-15
  105 +==================
  106 +
  107 + * Fixed `process.setuid()` typo
  108 +
  109 +0.0.1 / 2011-02-15
  110 +==================
  111 +
  112 + * Initial commit
22 node/server/node_modules/cluster/LICENSE
... ... @@ -0,0 +1,22 @@
  1 +(The MIT License)
  2 +
  3 +Copyright (c) 2011 LearnBoost <dev@learnboost.com>
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining
  6 +a copy of this software and associated documentation files (the
  7 +'Software'), to deal in the Software without restriction, including
  8 +without limitation the rights to use, copy, modify, merge, publish,
  9 +distribute, sublicense, and/or sell copies of the Software, and to
  10 +permit persons to whom the Software is furnished to do so, subject to
  11 +the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be
  14 +included in all copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  20 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 node/server/node_modules/cluster/Makefile
... ... @@ -0,0 +1,8 @@
  1 +
  2 +test:
  3 + @./test/run
  4 +
  5 +test-debug:
  6 + @./test/run debug
  7 +
  8 +.PHONY: test test-debug
98 node/server/node_modules/cluster/Readme.md
Source Rendered
... ... @@ -0,0 +1,98 @@
  1 +
  2 +# Cluster
  3 +
  4 + [Cluster](http://learnboost.github.com/cluster) is an extensible multi-core server manager for [node.js](http://nodejs.org).
  5 +
  6 +## Installation
  7 +
  8 + $ npm install cluster
  9 +
  10 +## Features
  11 +
  12 + - zero-downtime restart
  13 + - hard shutdown support
  14 + - graceful shutdown support
  15 + - resuscitates workers
  16 + - maintains worker count, even if worker was _SIGKILL_ed.
  17 + - workers commit suicide when master dies
  18 + - spawns one worker per cpu (by default)
  19 + - extensible via plugins
  20 + - bundled plugins
  21 + - [cli](http://learnboost.github.com/cluster/docs/cli.html): provides a command-line interface for your cluster
  22 + - [debug](http://learnboost.github.com/cluster/docs/debug.html): verbose debugging information
  23 + - [logger](http://learnboost.github.com/cluster/docs/logger.html): master / worker logs
  24 + - [pidfiles](http://learnboost.github.com/cluster/docs/pidfiles.html): writes master / worker pidfiles
  25 + - [reload](http://learnboost.github.com/cluster/docs/reload.html): reloads workers when files change
  26 + - [repl](http://learnboost.github.com/cluster/docs/repl.html): perform real-time administration
  27 + - [stats](http://learnboost.github.com/cluster/docs/stats.html): adds real-time statistics to the `repl` plugin
  28 + - supports node 0.2.x
  29 + - supports node 0.4.x
  30 + - supports TCP servers
  31 +
  32 +## Example
  33 +
  34 + var cluster = require('cluster')
  35 + , http = require('http');
  36 +
  37 + var server = http.createServer(function(req, res){
  38 + console.log('%s %s', req.method, req.url);
  39 + var body = 'Hello World';
  40 + res.writeHead(200, { 'Content-Length': body.length });
  41 + res.end(body);
  42 + });
  43 +
  44 + cluster(server)
  45 + .use(cluster.logger('logs'))
  46 + .use(cluster.stats())
  47 + .use(cluster.pidfiles('pids'))
  48 + .use(cluster.cli())
  49 + .use(cluster.repl(8888))
  50 + .listen(3000);
  51 +
  52 +# Screencasts
  53 +
  54 + - Cluster [Introduction](http://screenr.com/X8v)
  55 +
  56 +## Running Tests
  57 +
  58 +First:
  59 +
  60 + $ git submodule update --init
  61 +
  62 +Then:
  63 +
  64 + $ make test
  65 +
  66 +Actively tested with node:
  67 +
  68 + - 0.2.6
  69 + - 0.4.1
  70 +
  71 +## Authors
  72 +
  73 + * TJ Holowaychuk
  74 +
  75 +## License
  76 +
  77 +(The MIT License)
  78 +
  79 +Copyright (c) 2011 LearnBoost &lt;dev@learnboost.com&gt;
  80 +
  81 +Permission is hereby granted, free of charge, to any person obtaining
  82 +a copy of this software and associated documentation files (the
  83 +'Software'), to deal in the Software without restriction, including
  84 +without limitation the rights to use, copy, modify, merge, publish,
  85 +distribute, sublicense, and/or sell copies of the Software, and to
  86 +permit persons to whom the Software is furnished to do so, subject to
  87 +the following conditions:
  88 +
  89 +The above copyright notice and this permission notice shall be
  90 +included in all copies or substantial portions of the Software.
  91 +
  92 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  93 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  94 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  95 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  96 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  97 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  98 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BIN  node/server/node_modules/cluster/docs/._api.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._cli.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._debug.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._logger.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._pidfiles.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._reload.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._repl.md
Source Rendered
Binary file not shown
BIN  node/server/node_modules/cluster/docs/._stats.md
Source Rendered
Binary file not shown
198 node/server/node_modules/cluster/docs/api.md
Source Rendered
... ... @@ -0,0 +1,198 @@
  1 +
  2 +## API
  3 +
  4 + The Cluster API at its core is extremely simple, all we need to do is pass
  5 + our tcp or http `server` to `cluster()`, then call `listen()` as we would on the `http.Server` itself.
  6 +
  7 +
  8 + var cluster = require('../')
  9 + , http = require('http');
  10 +
  11 + var server = http.createServer(function(req, res){
  12 + res.writeHead(200);
  13 + res.end('Hello World');
  14 + });
  15 +
  16 + cluster(server)
  17 + .listen(3000);
  18 +
  19 + Alternatively (and recommended) is to export your server instance via `module.exports`, and supply a path to `cluster()`. For example _app.js_:
  20 +
  21 + module.exports = http.createServer(....);
  22 +
  23 + and _server.js_ with our cluster logic, allowing our server to be `require()`ed within tests, and preventing potential issues by having open database connections etc within the master processes, as only the workers need access to the `server` instance.
  24 +
  25 + cluster('app')
  26 + .listen(3000);
  27 +
  28 + A good example if this, is a long-lived database connection. Our _app.js_ may have this initialized at the top, which although will work fine stand-alone, may cause cluster's master processes to hang when restarting or closing due to the connection remaining active in the event loop.
  29 +
  30 + var db = redis.createClient();
  31 +
  32 +### Plugins
  33 +
  34 + A plugin simple a function that accepts the `master` process. Most plugin functions _return_ another anonymous function, allowing them to accept options, for example:
  35 +
  36 + function myPlugin(path){
  37 + return function(master) {
  38 + // do stuff
  39 + }
  40 + }
  41 +
  42 + To use them, all we need to do is pass it to the `use()` method:
  43 +
  44 + cluster(server)
  45 + .use(myPlugin('/some/path'))
  46 + .listen(3000);
  47 +
  48 + To use a plugin that is bundled with Cluster simply grab it from the `cluster` object:
  49 +
  50 + cluster(server)
  51 + .use(cluster.logger())
  52 + .listen(3000);
  53 +
  54 +### Settings
  55 +
  56 + Below are the settings available:
  57 +
  58 + - `workers` Number of workers to spawn, defaults to the number of CPUs or `1`
  59 + - `working directory` Working directory defaulting to the script's dir
  60 + - `backlog` Connection backlog, defaulting to 128
  61 + - `socket path` Master socket path defaulting to `./`
  62 + - `timeout` Worker shutdown timeout in milliseconds, defaulting to `60000`
  63 + - `user` User id / name
  64 + - `group` Group id / name
  65 +
  66 + We can take what we have now, and go on to apply settings using the `set(option, value)` method. For example:
  67 +
  68 + cluster(server)
  69 + .set('working directory', '/')
  70 + .set('workers', 5)
  71 + .listen(3000);
  72 +
  73 +### Signals
  74 +
  75 + Cluster performs the following actions when handling signals:
  76 +
  77 + - `SIGINT` hard shutdown
  78 + - `SIGTERM` hard shutdown
  79 + - `SIGQUIT` graceful shutdown
  80 + - `SIGUSR2` restart workers
  81 +
  82 +### Events
  83 +
  84 + The following events are emitted, useful for plugins or general purpose logging etc.
  85 +
  86 + - `start`. When the server is starting (pre-spawn)
  87 + - `worker`. When a worker is spawned, passing the `worker`
  88 + - `listening`. When the server is listening for connections (post-spawn)
  89 + - `closing`. When master is gracefully shutting down
  90 + - `close`. When master has completed shutting down
  91 + - `worker killed`. When a worker has died
  92 + - `worker exception`. Worker uncaughtException. Receives the worker and exception object
  93 + - `kill`. When a `signal` is being sent to all workers
  94 + - `restarting`. Restart requested by REPL or signal. Receives an object
  95 + which can be patched in order to preserve plugin state.
  96 + - `restart`. Restart complete, new master established, previous killed.
  97 + Receives an object with state preserved by the `restarting` even,
  98 + patched in the previous master.
  99 +
  100 +### Master#state
  101 +
  102 + Current state of the master process, one of:
  103 +
  104 + - `active`
  105 + - `hard shutdown`
  106 + - `graceful shutdown`
  107 +
  108 +### Master#isWorker
  109 +
  110 + `true` when the script is executed as a worker.
  111 +
  112 + cluster = cluster(server).listen(3000);
  113 +
  114 + if (cluster.isWorker) {
  115 + // do something
  116 + }
  117 +
  118 +### Master#isMaster
  119 +
  120 +`true` when the script is executed as master.
  121 +
  122 + cluster = cluster(server).listen(3000);
  123 +
  124 + if (cluster.isMaster) {
  125 + // do something
  126 + }
  127 +
  128 +### Master#set(option, value)
  129 +
  130 + Set `option` to `value`.
  131 +
  132 +### Master#use(plugin)
  133 +
  134 + Register a `plugin` for use.
  135 +
  136 +### Master#in(env)
  137 +
  138 + Conditionally perform the following action, if
  139 + __NODE_ENV__ matches `env`.
  140 +
  141 + cluster(server)
  142 + .in('development').use(cluster.debug())
  143 + .in('development').listen(3000)
  144 + .in('production').listen(80);
  145 +
  146 + The environment conditionals may be applied to several calls:
  147 +
  148 + cluster(server)
  149 + .set('working directory', '/')
  150 + .in('development')
  151 + .set('workers', 1)
  152 + .use(cluster.logger('logs', 'debug'))
  153 + .use(cluster.debug())
  154 + .listen(3000)
  155 + .in('production')
  156 + .set('workers', 4)
  157 + .use(cluster.logger())
  158 + .use(cluster.pidfiles())
  159 + .listen(80);
  160 +
  161 + If we perform the same action for environments, set them before
  162 + the first `in()` call, or use `in('all')`.
  163 +
  164 + cluster(server)
  165 + .set('working directory', '/')
  166 + .do(function(){
  167 + console.log('some arbitrary action');
  168 + })
  169 + .in('development')
  170 + .set('workers', 1)
  171 + .use(cluster.logger('logs', 'debug'))
  172 + .use(cluster.debug())
  173 + .in('production')
  174 + .set('workers', 4)
  175 + .use(cluster.logger())
  176 + .use(cluster.pidfiles())
  177 + .in('all')
  178 + .listen(80);
  179 +
  180 +### Master#spawn(n)
  181 +
  182 + Spawn `n` additional workers.
  183 +
  184 +### Master#close()
  185 +
  186 + Graceful shutdown, waits for all workers to reply before exiting.
  187 +
  188 +### Master#destroy()
  189 +
  190 + Hard shutdown, immediately kill all workers.
  191 +
  192 +### Master#restart([signal])
  193 +
  194 + Defaults to a graceful restart, spawning a new master process, and sending __SIGQUIT__ to the previous master process. Alternatively a custom `signal` may be passed.
  195 +
  196 +### Master#kill([signal])
  197 +
  198 + Sends __SIGTERM__ or `signal` to all worker processes. This method is used by `Master#restart()`, `Master#close()` etc.
59 node/server/node_modules/cluster/docs/cli.md
Source Rendered
... ... @@ -0,0 +1,59 @@
  1 +
  2 +## CLI
  3 +
  4 + Adds a command-line interface to your cluster.
  5 +
  6 +### Usage
  7 +
  8 +This plugin requires that you use `pidfiles()`
  9 +above `cli()`, so that the pidfile directory
  10 +is exposed.
  11 +
  12 + cluster(server)
  13 + .use(cluster.pidfiles())
  14 + .use(cluster.cli())
  15 + .listen(3000);
  16 +
  17 +Once set up our server script serves as both
  18 +the master, and the CLI. For example we may
  19 +still launch the server(s) as shown below.
  20 +
  21 + $ nohup node server.js &
  22 +
  23 +However now we may also utilize commands
  24 +provided by this plugin.
  25 +
  26 + $ node server.js status
  27 +
  28 + master 3281 alive
  29 + worker 0 3282 dead
  30 + worker 1 3283 alive
  31 + worker 2 3284 alive
  32 + worker 3 3285 alive
  33 +
  34 + $ node server.js restart
  35 + $ node server.js shutdown
  36 +
  37 +For more command information use `--help`.
  38 +
  39 + $ node server.js --help
  40 +
  41 +### Defining CLI Commands
  42 +
  43 + Plugins may define additional commands, simply by invoking `cluster.cli.define()` passing the flag(s), a callback function,
  44 + and a description. Below is the implementation of `--help` for reference:
  45 +
  46 + var cli = require('cluster').cli;
  47 +
  48 + cli.define('-h, --help, help', function(master){
  49 + console.log('\n Usage: node <file> <command>\n');
  50 + commands.forEach(function(command){
  51 + console.log(' '
  52 + + command.flags.join(', ')
  53 + + '\n '
  54 + + '\033[90m' + command.desc + '\033[0m'
  55 + + '\n');
  56 + });
  57 + console.log();
  58 + process.exit();
  59 + }, 'Show help information');
27 node/server/node_modules/cluster/docs/debug.md
Source Rendered
... ... @@ -0,0 +1,27 @@
  1 +
  2 +## Debug
  3 +
  4 +Outputs verbose debugging information to _stderr_.
  5 +
  6 + info - master started
  7 + info - worker 0 spawned
  8 + info - worker 1 spawned
  9 + info - worker 2 spawned
  10 + info - worker 3 spawned
  11 + info - worker 2 connected
  12 + info - worker 0 connected
  13 + info - worker 3 connected
  14 + info - worker 1 connected
  15 + info - listening for connections
  16 + ^C info - shutting down
  17 + warning - kill(SIGKILL)
  18 + info - shutdown complete
  19 + warning - worker 2 died
  20 + warning - worker 0 died
  21 + warning - worker 3 died
  22 +
  23 +## Usage
  24 +
  25 + cluster(server)
  26 + .use(cluster.debug())
  27 + .listen(3000);
33 node/server/node_modules/cluster/docs/logger.md
Source Rendered
... ... @@ -0,0 +1,33 @@
  1 +
  2 +## Logger
  3 +
  4 + File-based logging of both the _master_ and _worker_ processes.
  5 +
  6 +### Usage
  7 +
  8 +The `logger([path[, level]])` plugin accepts an optional `path`, and optional `level` to control the verbosity of the master process logs. By default the log level is _info_.
  9 +
  10 +Outputting to `./logs`:
  11 +
  12 + cluster(server)
  13 + .use(cluster.logger())
  14 + .listen(3000);
  15 +
  16 +
  17 +Outputting to `./tmp/logs`:
  18 +
  19 + cluster(server)
  20 + .use(cluster.logger('tmp/logs'))
  21 + .listen(3000);
  22 +
  23 +Outputting to `/var/log/node` with a log level of `debug`:
  24 +
  25 + cluster(server)
  26 + .use(cluster.logger('/var/log/node', 'debug'))
  27 + .listen(3000);
  28 +
  29 +Generated files:
  30 +
  31 + master.log
  32 + workers.access.log
  33 + workers.error.log
41 node/server/node_modules/cluster/docs/pidfiles.md
Source Rendered
... ... @@ -0,0 +1,41 @@
  1 +
  2 +## PID Files
  3 +
  4 + Saves out PID files, for example:
  5 +
  6 + master.pid
  7 + worker.0.pid
  8 + worker.1.pid
  9 + worker.2.pid
  10 + worker.3.pid
  11 +
  12 +### Usage
  13 +
  14 +The `pidfiles([path])` plugin saves pid (process-id) files to the given `path` or `./pids`.
  15 +
  16 +save to `./pids`:
  17 +
  18 + cluster(server)
  19 + .use(cluster.pidfiles())
  20 + .listen(3000);
  21 +
  22 +save to `/var/run/node`:
  23 +
  24 + cluster(server)
  25 + .use(cluster.logger('/var/run/node'))
  26 + .listen(3000);
  27 +
  28 +### master.pidfiles
  29 +
  30 + The pidfiles directory.
  31 +
  32 +### master.pidof(name)
  33 +
  34 + Return a __PID__ for the given `name`.
  35 +
  36 + master.pidof('master')
  37 + // => 5978
  38 +
  39 + master.pidof('worker.0')
  40 + // => 5979
  41 +
39 node/server/node_modules/cluster/docs/reload.md
Source Rendered
... ... @@ -0,0 +1,39 @@
  1 +
  2 +## Reload
  3 +
  4 + Restart the server the given js `files` have changed.
  5 + `files` may be several directories, filenames, etc, defaulting
  6 + to the script's directory.
  7 +
  8 +### Options
  9 +
  10 + - `signal` Signal to send, defaults to __SIGTERM__
  11 + - `interval` Watcher interval, defaulting to `100`
  12 +
  13 +### Usage
  14 +
  15 + The `reload(paths[, signal])` plugin accepts a single path, or an array of paths, watching for __mtime__ changes, and re-loading the workers when a change has been made. By default the __SIGTERM__ signal is sent, killing the workers immediately, however we may pass a `signal` for graceful termination as well.
  16 +
  17 + Reload when files in `./` (`__dirname`) change:
  18 +
  19 + cluster(server)
  20 + .use(cluster.reload())
  21 + .listen(3000);
  22 +
  23 + Reload when files in `./lib` change:
  24 +
  25 + cluster(server)
  26 + .use(cluster.reload('lib'))
  27 + .listen(3000);
  28 +
  29 + Reload when files in `./lib`, `./tests`, or the `./index.js` file change:
  30 +
  31 + cluster(server)
  32 + .use(cluster.reload(['lib', 'tests', 'index.js']))
  33 + .listen(3000);
  34 +
  35 + Graceful shutdown:
  36 +
  37 + cluster(server)
  38 + .use(cluster.reload('lib', { signal: 'SIGQUIT' }))
  39 + .listen(3000);
164 node/server/node_modules/cluster/docs/repl.md
Source Rendered
... ... @@ -0,0 +1,164 @@
  1 +
  2 +## REPL
  3 +
  4 + Provides live administration tools for inspecting state, spawning and killing workers, and more. The __REPL__ plugin itself is extensible, for example the `stats()` plugin provides a __REPL__ function named `stats()`.
  5 +
  6 +### Usage
  7 +
  8 + The `repl([port | path])` accepts a `port` or unix domain socket `path`, after which you may telnet to at any time.
  9 +
  10 +Launch the __REPL__ on port _8888_:
  11 +
  12 + cluster(server)
  13 + .use(cluster.repl(8888, '127.0.0.1'))
  14 + .listen(3000);
  15 +
  16 +Start a telnet session:
  17 +
  18 + $ telnet localhost 8888
  19 +
  20 + cluster> help()
  21 +
  22 + Commands
  23 + help(): Display help information
  24 + spawn(n): Spawn one or more additional workers
  25 + pids(): Output process ids
  26 + kill(id, signal): Send signal or SIGTERM to the given worker
  27 + shutdown(): Gracefully shutdown server
  28 + stop(): Hard shutdown
  29 + restart(): Gracefully restart all workers
  30 + echo(msg): echo the given message
  31 + stats(): Display server statistics
  32 +
  33 +
  34 +### pids()
  35 +
  36 + Outputs the master / worker process ids.
  37 +
  38 + cluster> pids()
  39 +
  40 + pids
  41 + master: 1799
  42 + worker #0: 1801
  43 + worker #1: 1802
  44 + worker #2: 1803
  45 + worker #3: 1804
  46 +
  47 +### spawn()
  48 +
  49 + Spawn an additional worker.
  50 +
  51 + cluster> spawn()
  52 + spawning 1 worker
  53 + cluster> pids()
  54 +
  55 + pids
  56 + master: 1799
  57 + worker #0: 1801
  58 + worker #1: 1802
  59 + worker #2: 1803
  60 + worker #3: 1804
  61 + worker #4: 1809
  62 +
  63 +### spawn(n)
  64 +
  65 + Spawn `n` workers:
  66 +
  67 + cluster> spawn(4)
  68 + spawning 4 workers
  69 + cluster> pids()
  70 +
  71 + pids
  72 + master: 1817
  73 + worker #0: 1818
  74 + worker #1: 1819
  75 + worker #2: 1820
  76 + worker #3: 1821
  77 + worker #4: 1825
  78 + worker #5: 1826
  79 + worker #6: 1827
  80 + worker #7: 1828
  81 +
  82 +### kill(id[, signal])
  83 +
  84 +Kill worker `id` with the given `signal` or __SIGTERM__. For graceful termination use __SIGQUIT__.
  85 +
  86 + cluster> pids()
  87 +
  88 + pids
  89 + master: 1835
  90 + worker #0: 1837
  91 + worker #1: 1838
  92 + worker #2: 1839
  93 + worker #3: 1840
  94 +
  95 + cluster> kill(2)
  96 + sent SIGTERM to worker #2
  97 + cluster> kill(3)
  98 + sent SIGTERM to worker #3
  99 + cluster> pids()
  100 +
  101 + pids
  102 + master: 1835
  103 + worker #0: 1837
  104 + worker #1: 1838
  105 + worker #2: 1843
  106 + worker #3: 1844
  107 +
  108 +### restart()
  109 +
  110 + Gracefully restart all workers.
  111 +
  112 + cluster> pids()
  113 +
  114 + pids
  115 + master: 1835
  116 + worker #0: 1837
  117 + worker #1: 1838
  118 + worker #2: 1843
  119 + worker #3: 1844
  120 +
  121 + cluster> restart()
  122 + restarting 4 workers
  123 + cluster> pids()
  124 +
  125 + pids
  126 + master: 1835
  127 + worker #0: 1845
  128 + worker #1: 1849
  129 + worker #2: 1848
  130 + worker #3: 1847
  131 +
  132 +### Defining REPL Functions
  133 +
  134 + To define a function accessible to the __REPL__, all we need to do is call `cluster.repl.define()`, passing the function, as well as a description string.
  135 +
  136 + Below we define the `echo()` function, simply printing the input `msg` given. As you can see our function receivers the `Master` instance, the __REPL__ `sock`, and any arguments that were passed. For example `echo("test")` would pass the `msg` as `"test"`, and `echo("foo", "bar")` would pass `msg` as `"foo"`, and `arguments[3]` as `"bar"`.
  137 +
  138 + repl.define('echo', function(master, sock, msg){
  139 + sock.write(msg + '\n');
  140 + }, 'echo the given message');
  141 +
  142 + Shown below is a more complete example.
  143 +
  144 + var cluster = require('../')
  145 + , repl = cluster.repl
  146 + , http = require('http');
  147 +
  148 + var server = http.createServer(function(req, res){
  149 + var body = 'Hello World';
  150 + res.writeHead(200, { 'Content-Length': body.length });
  151 + res.end(body);
  152 + });
  153 +
  154 + // custom repl function
  155 +
  156 + repl.define('echo', function(master, sock, msg){
  157 + sock.write(msg + '\n');
  158 + }, 'echo the given message');
  159 +
  160 + // $ telnet localhots 8888
  161 +
  162 + cluster(server)
  163 + .use(repl(8888))
  164 + .listen(3000);
45 node/server/node_modules/cluster/docs/stats.md
Source Rendered
... ... @@ -0,0 +1,45 @@
  1 +
  2 +## Stats
  3 +
  4 + The stats plugin collects statistics from the events emitter by the master process, and exposes a `stats()` __REPL__ function.
  5 +
  6 +
  7 +### Usage
  8 +
  9 +To utilize simply `use()` both the `stats()` and `repl()` plugins.
  10 +
  11 + cluster(server)
  12 + .use(cluster.stats())
  13 + .use(cluster.repl(8888))
  14 + .listen(3000);
  15 +
  16 +Telnet to the repl:
  17 +
  18 + $ telnet localhost 8888
  19 +
  20 +### stats()
  21 +
  22 + After manually killing two workers, the stats below show information regarding system load average, uptime, total workers spawned, deaths, worker-specific stats and more.
  23 +
  24 + cluster> stats()
  25 +
  26 + Master
  27 + os: Darwin 10.5.0
  28 + state: active
  29 + started: Fri, 11 Feb 2011 16:58:48 GMT
  30 + uptime: 2 minutes
  31 + workers: 4
  32 + deaths: 2
  33 +
  34 + Resources
  35 + load average: 0.35 0.23 0.15
  36 + cores utilized: 4 / 4
  37 + memory at boot (free / total): 2.18gb / 4.00gb
  38 + memory now (free / total): 2.08gb / 4.00gb
  39 +
  40 + Workers
  41 + uptime #0: 2 minutes
  42 + uptime #1: 2 minutes
  43 + uptime #2: 1 minute
  44 + uptime #3: 22 seconds
  45 +
2  node/server/node_modules/cluster/index.js
... ... @@ -0,0 +1,2 @@
  1 +
  2 +module.exports = require('./lib/cluster');
BIN  node/server/node_modules/cluster/lib/._cluster.js
Binary file not shown
BIN  node/server/node_modules/cluster/lib/._master.js
Binary file not shown
BIN  node/server/node_modules/cluster/lib/._worker.js
Binary file not shown
48 node/server/node_modules/cluster/lib/cluster.js
... ... @@ -0,0 +1,48 @@
  1 +
  2 +/*!
  3 + * Cluster
  4 + * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
  5 + * MIT Licensed
  6 + */
  7 +
  8 +/**
  9 + * Module dependencies.
  10 + */
  11 +
  12 +var Master = require('./master')
  13 + , fs = require('fs');
  14 +
  15 +/**
  16 + * Export `start` as the module.
  17 + */
  18 +
  19 +exports = module.exports = start;
  20 +
  21 +/**
  22 + * Library version.
  23 + */
  24 +
  25 +exports.version = '0.3.1';
  26 +
  27 +/**
  28 + * Start a new `Master` with the given `server`.
  29 + *
  30 + * @param {http.Server} server
  31 + * @return {Master}
  32 + * @api public
  33 + */
  34 +
  35 +function start(server) {
  36 + return new Master(server);
  37 +}
  38 +
  39 +/**
  40 + * Expose middleware via lazy-requires.
  41 + */
  42 +
  43 +fs.readdirSync(__dirname + '/plugins').forEach(function(plugin){
  44 + plugin = plugin.replace('.js', '');
  45 + exports.__defineGetter__(plugin, function(){
  46 + return require('./plugins/' + plugin);
  47 + });
  48 +});
755 node/server/node_modules/cluster/lib/master.js
... ... @@ -0,0 +1,755 @@
  1 +
  2 +/*!
  3 + * Cluster - Master
  4 + * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
  5 + * MIT Licensed
  6 + */
  7 +
  8 +/**
  9 + * Module dependencies.
  10 + */
  11 +
  12 +var Worker = require('./worker')
  13 + , EventEmitter = require('events').EventEmitter
  14 + , binding = process.binding('net')
  15 + , dirname = require('path').dirname
  16 + , spawn = require('child_process').spawn
  17 + , ENOENT = process.version >= 'v0.4.0'
  18 + ? require('constants').ENOENT
  19 + : process.ENOENT
  20 + , net = require('net')
  21 + , fs = require('fs')
  22 + , os;
  23 +
  24 +// COMPAT:
  25 +
  26 +try {
  27 + os = require('os');
  28 +} catch (err) {
  29 + // ignore
  30 +}
  31 +
  32 +// COMPAT:
  33 +
  34 +net.Socket = net.Stream;
  35 +
  36 +// COMPAT:
  37 +
  38 +if (!net.isIP) net.isIP = binding.isIP;
  39 +
  40 +/**
  41 + * Node binary.
  42 + */
  43 +
  44 +var node = process.execPath
  45 +
  46 +/**
  47 + * Start a new `Master` with the given `server` or filename to
  48 + * a node module exporting a server.
  49 + *
  50 + * Options:
  51 + *
  52 + * - `workers` Number of workers to spawn, defaults to the number of CPUs
  53 + * - 'working directory` Working directory defaulting to the script's dir
  54 + * - 'backlog` Connection backlog, defaulting to 128
  55 + * - 'socket path` Master socket path defaulting to `./`
  56 + * - 'timeout` Worker shutdown timeout in milliseconds, defaulting to 60,000
  57 + * - 'user` User id / name
  58 + * - 'group` Group id / name
  59 + *
  60 + * Events:
  61 + *
  62 + * - `start`. When the server is starting (pre-spawn)
  63 + * - `worker`. When a worker is spawned, passing the `worker`
  64 + * - `listening`. When the server is listening for connections (post-spawn)
  65 + * - `closing`. When master is gracefully shutting down
  66 + * - `close`. When master has completed shutting down
  67 + * - `worker killed`. When a worker has died
  68 + * - `worker exception`. Worker uncaughtException. Receives the worker / exception
  69 + * - `kill`. When a `signal` is being sent to all workers
  70 + * - `restarting`. Restart requested by REPL or signal. Receives an object
  71 + * which can be patched in order to preserve plugin state.
  72 + * - `restart`. Restart complete, new master established, previous died.
  73 + * Receives an object with state preserved by the `restarting` event.
  74 + *
  75 + * Signals:
  76 + *
  77 + * - `SIGINT` hard shutdown