| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | // TODO if RAM is very low we should not fork at all,
 | 
					
						
							|  |  |  | // but use a different process altogether
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-17 08:18:56 +00:00
										 |  |  | console.info('pid:', process.pid); | 
					
						
							|  |  |  | console.info('title:', process.title); | 
					
						
							|  |  |  | console.info('arch:', process.arch); | 
					
						
							|  |  |  | console.info('platform:', process.platform); | 
					
						
							|  |  |  | console.info('\n\n\n[MASTER] Welcome to WALNUT!'); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-31 12:30:04 -04:00
										 |  |  | function tryConf(pathname, def) { | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     return require(pathname); | 
					
						
							|  |  |  |   } catch(e) { | 
					
						
							|  |  |  |     return def; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-28 21:12:35 -04:00
										 |  |  | var path = require('path'); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | var cluster = require('cluster'); | 
					
						
							| 
									
										
										
										
											2015-11-17 08:18:56 +00:00
										 |  |  | //var minWorkers = 2;
 | 
					
						
							| 
									
										
										
										
											2015-11-19 07:42:20 +00:00
										 |  |  | var numCores = 2; // Math.max(minWorkers, require('os').cpus().length);
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | var workers = []; | 
					
						
							| 
									
										
										
										
											2016-03-31 02:39:15 -04:00
										 |  |  | var state = { firstRun: true }; | 
					
						
							| 
									
										
										
										
											2016-03-31 12:30:04 -04:00
										 |  |  | // TODO Should these be configurable? If so, where?
 | 
					
						
							|  |  |  | // TODO communicate config with environment vars?
 | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  | var walnut = tryConf( | 
					
						
							|  |  |  |   path.join('..', '..', 'config.walnut') | 
					
						
							|  |  |  | , { externalPort: 443 | 
					
						
							|  |  |  |   , externalInsecurePort: 80 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | ); | 
					
						
							| 
									
										
										
										
											2017-05-04 23:09:56 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-31 12:30:04 -04:00
										 |  |  | var info = { | 
					
						
							|  |  |  |   type: 'walnut.init' | 
					
						
							|  |  |  | , conf: { | 
					
						
							| 
									
										
										
										
											2017-05-04 23:09:56 -06:00
										 |  |  |     protocol: 'http' | 
					
						
							|  |  |  |   , externalPort: walnut.externalPort || 443 | 
					
						
							|  |  |  |   , externalPortInsecure: walnut.externalInsecurePort || 80   // TODO externalInsecurePort
 | 
					
						
							|  |  |  |   , localPort: walnut.localPort || 4080                       // system / local network
 | 
					
						
							|  |  |  |   , trustProxy: true | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |   , varpath: path.join(__dirname, '..', '..', 'var') | 
					
						
							| 
									
										
										
										
											2016-06-07 10:49:26 -04:00
										 |  |  |   , etcpath: path.join(__dirname, '..', '..', 'etc') | 
					
						
							| 
									
										
										
										
											2016-03-31 12:30:04 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-03-29 15:55:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | function fork() { | 
					
						
							|  |  |  |   if (workers.length < numCores) { | 
					
						
							|  |  |  |     workers.push(cluster.fork()); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cluster.on('online', function (worker) { | 
					
						
							| 
									
										
										
										
											2016-03-29 15:55:05 -04:00
										 |  |  |   console.info('[MASTER] Worker ' + worker.process.pid + ' is online'); | 
					
						
							|  |  |  |   fork(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-31 02:39:15 -04:00
										 |  |  |   if (state.firstRun) { | 
					
						
							|  |  |  |     state.firstRun = false; | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     // TODO dyndns in master?
 | 
					
						
							| 
									
										
										
										
											2016-03-31 02:39:15 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |   function touchMaster(msg) { | 
					
						
							| 
									
										
										
										
											2015-11-28 06:05:27 +00:00
										 |  |  |     if ('walnut.webserver.listening' !== msg.type) { | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |       console.warn('[MASTER] received unexpected message from worker'); | 
					
						
							|  |  |  |       console.warn(msg); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |     state.workers = workers; | 
					
						
							| 
									
										
										
										
											2016-04-09 19:14:00 -04:00
										 |  |  |     // calls init if init has not been called
 | 
					
						
							|  |  |  |     require('../lib/master').touch(info.conf, state).then(function (newConf) { | 
					
						
							|  |  |  |       worker.send({ type: 'walnut.webserver.onrequest', conf: newConf }); | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-03-31 02:39:15 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   worker.send(info); | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |   worker.on('message', touchMaster); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cluster.on('exit', function (worker, code, signal) { | 
					
						
							| 
									
										
										
										
											2015-11-17 08:18:56 +00:00
										 |  |  |   console.info('[MASTER] Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  |   workers = workers.map(function (w) { | 
					
						
							|  |  |  |     if (worker !== w) { | 
					
						
							|  |  |  |       return w; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   }).filter(function (w) { | 
					
						
							|  |  |  |     return w; | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-19 07:42:20 +00:00
										 |  |  |   //console.log('WARNING: worker spawning turned off for debugging ');
 | 
					
						
							|  |  |  |   fork(); | 
					
						
							| 
									
										
										
										
											2015-11-04 09:22:00 +00:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 11:05:32 +00:00
										 |  |  | fork(); |