1 | var path = require ('path');
|
2 | var cluster = require ('cluster');
|
3 | var os = require ('os');
|
4 |
|
5 | var numCPUs = os.cpus().length;
|
6 |
|
7 | var dataflows = require ('dataflo.ws');
|
8 | var minimist = require ('commop/lib/minimist');
|
9 |
|
10 | module.exports = {
|
11 | launchContext: function () {
|
12 | var argv = minimist(process.argv.slice(3));
|
13 | return {
|
14 | configKey: argv._[0],
|
15 | method: argv._[1],
|
16 | args: argv
|
17 | };
|
18 | },
|
19 | launch: function (conf) {
|
20 | var ctx = this.launchContext();
|
21 | var daemonName = ctx.configKey;
|
22 |
|
23 | if ('fork' in ctx.args && !ctx.args.fork) {
|
24 | runDaemon (conf, daemonName);
|
25 |
|
26 | return;
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | if (cluster.isMaster) {
|
32 |
|
33 | for (var i = 0; i < numCPUs; i++) {
|
34 | cluster.fork();
|
35 | }
|
36 |
|
37 | cluster.on('exit', function(worker, code, signal) {
|
38 |
|
39 | console.log('worker ' + worker.process.pid + ' died, code: ' + code + ', signal:' + signal);
|
40 | if (code != 0) {
|
41 | console.log("worker crashed! spawning a replacement.");
|
42 | cluster.fork();
|
43 | }
|
44 | });
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | process.on ('SIGHUP', gracefullyRestartWorkers);
|
52 |
|
53 | } else {
|
54 |
|
55 |
|
56 | runDaemon (conf, daemonName);
|
57 | }
|
58 |
|
59 |
|
60 | if (!project.config.debug) {
|
61 | return;
|
62 | }
|
63 |
|
64 | return;
|
65 |
|
66 | setupWatcher ();
|
67 | }
|
68 | }
|
69 |
|
70 | function killWorkers () {
|
71 | Object.keys(cluster.workers).forEach (function (workerNum) {
|
72 | cluster.workers[workerNum].kill ();
|
73 | });
|
74 | }
|
75 |
|
76 | function gracefullyRestartWorkers () {
|
77 |
|
78 |
|
79 | var i = 0;
|
80 | var workers = Object.keys(cluster.workers);
|
81 | var f = function() {
|
82 | if (i == workers.length) return;
|
83 |
|
84 | console.log("Killing " + workers[i]);
|
85 |
|
86 | cluster.workers[workers[i]].disconnect();
|
87 | cluster.workers[workers[i]].on("disconnect", function() {
|
88 | console.log("worker shutdown complete");
|
89 | });
|
90 |
|
91 |
|
92 |
|
93 | var newWorker = cluster.fork();
|
94 | newWorker.on("listening", function() {
|
95 | console.log("replacement worker online.");
|
96 | i++;
|
97 | f();
|
98 | });
|
99 | }
|
100 | f();
|
101 | }
|
102 |
|
103 |
|
104 |
|
105 | function runDaemon (conf, daemonName) {
|
106 | var configDaemonNames = Object.keys(conf.daemon);
|
107 | if (daemonName == undefined && configDaemonNames.length == 1)
|
108 | daemonName = configDaemonNames[0];
|
109 | if (!conf.daemon || !conf.daemon[daemonName]) {
|
110 |
|
111 | console.error(
|
112 | 'No daemon named "%s" found in configuration', daemonName
|
113 | );
|
114 | var logDaemonNames = configDaemonNames.join ('", "');
|
115 | console.error ('You can select one from those daemon configurations: "%s"', logDaemonNames);
|
116 | process.exit();
|
117 | }
|
118 |
|
119 | var daemonConf = conf.daemon[daemonName];
|
120 | var initiatorTypes = daemonConf.initiator;
|
121 |
|
122 | var initiators = {};
|
123 |
|
124 | initiatorTypes.forEach(function (initiatorType) {
|
125 | var initiatorConf = conf.initiator[initiatorType];
|
126 |
|
127 |
|
128 | var initiatorClass = dataflows.initiator (initiatorType);
|
129 |
|
130 | if ('function' == typeof initiatorClass) {
|
131 | initiators[initiatorType] = new initiatorClass (initiatorConf, initiators);
|
132 | } else {
|
133 | console.error('Cannot load initiator "%s"', initiatorType);
|
134 | }
|
135 | });
|
136 | }
|
137 |
|
138 | function setupWatcher () {
|
139 |
|
140 | if (os.platform() === "darwin") {
|
141 | var fsevents = require('fsevents');
|
142 | var watcher = fsevents(__dirname);
|
143 | watcher.on('fsevent', function(path, flags, id) { });
|
144 | watcher.on('change', function(path, info) {});
|
145 | watcher.start()
|
146 | watcher.stop()
|
147 | } else {
|
148 |
|
149 | }
|
150 | var chokidar = require ('chokidar');
|
151 |
|
152 | var watcher = chokidar.watch([
|
153 | path.join (project.root.path, '.dataflows'),
|
154 | path.join (project.root.path, 'node_modules')
|
155 | ], {
|
156 |
|
157 | persistent: true
|
158 | });
|
159 |
|
160 |
|
161 | watcher
|
162 | .on('add', function(path) { log('File', path, 'has been added'); })
|
163 | .on('change', function(path) { log('File', path, 'has been changed'); })
|
164 | .on('unlink', function(path) { log('File', path, 'has been removed'); })
|
165 |
|
166 | .on('addDir', function(path) { log('Directory', path, 'has been added'); })
|
167 | .on('unlinkDir', function(path) { log('Directory', path, 'has been removed'); })
|
168 | .on('error', function(error) { log('Error happened', error); })
|
169 | .on('ready', function() { log('Initial scan complete. Ready for changes.'); })
|
170 | .on('raw', function(event, path, details) { log('Raw event info:', event, path, details); })
|
171 |
|
172 | }
|