forked from coolaj86/walnut.js
		
	
		
			
	
	
		
			114 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | module.exports.create = function (conf, deps) { | ||
|  |   var PromiseA = deps.Promise; | ||
|  | 
 | ||
|  |   function loadService(node) { | ||
|  |     var path = require('path'); | ||
|  | 
 | ||
|  |     return new PromiseA(function (resolve) { | ||
|  |       // process.nextTick runs at the end of the current event loop
 | ||
|  |       // we actually want time to pass so that potential api traffic can be handled
 | ||
|  |       setTimeout(function () { | ||
|  |         var servicepath = path.join(conf.servicespath, node); | ||
|  |         var pkg; | ||
|  | 
 | ||
|  |         try { | ||
|  |           // TODO no package should be named package.json
 | ||
|  |           pkg = require(servicepath + '/package.json'); | ||
|  |           resolve({ | ||
|  |             pkg: pkg | ||
|  |           , name: node | ||
|  |           , service: require(servicepath) | ||
|  |           }); | ||
|  |           return; | ||
|  |         } catch(e) { | ||
|  |           // TODO report errors to admin console
 | ||
|  |           // TODO take sha256sum of e.stack and store in db with tick for updatedAt
 | ||
|  |           console.error("[Service] could not require service '" + servicepath + "'"); | ||
|  |           console.error(e.stack); | ||
|  |           //services.push({ error: e });
 | ||
|  |           resolve(null); | ||
|  |           return; | ||
|  |         } | ||
|  |       }, 1); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function loadServices() { | ||
|  |     var fs = PromiseA.promisifyAll(require('fs')); | ||
|  | 
 | ||
|  |     // deps : { memstore, sqlstores, clientSqlFactory, systemSqlFactory }
 | ||
|  |      | ||
|  |     // XXX this is a no-no (file system access in a worker, cannot be statically analyzed)
 | ||
|  |     // TODO regenerate a static file of all requires on each install
 | ||
|  |     // TODO read system config db to find which services auto-start
 | ||
|  |     // TODO allow certain apis access to certain services
 | ||
|  |     return fs.readdirAsync(conf.servicespath).then(function (nodes) { | ||
|  |       var promise = PromiseA.resolve(); | ||
|  |       var services = []; | ||
|  |        | ||
|  |       nodes.forEach(function (node) { | ||
|  |         promise = promise.then(function () { | ||
|  |           return loadService(node).then(function (srv) { | ||
|  |             if (!srv) { | ||
|  |               return; | ||
|  |             } | ||
|  |             services.push(srv); | ||
|  |           }); | ||
|  |         }); | ||
|  |       }); | ||
|  | 
 | ||
|  |       return promise.then(function () { | ||
|  |         return services; | ||
|  |       }); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function startService(srv) { | ||
|  |     return new PromiseA(function (resolve) { | ||
|  |       // process.nextTick runs at the end of the current event loop
 | ||
|  |       // we actually want time to pass so that potential api traffic can be handled
 | ||
|  |       setTimeout(function () { | ||
|  |         try { | ||
|  |           PromiseA.resolve(srv.service.create(conf, deps)).then(resolve, function (e) { | ||
|  |             console.error("[Service] couldn't promise service"); | ||
|  |             console.error(e.stack); | ||
|  |             resolve(null); | ||
|  |           }); | ||
|  |           return; | ||
|  |         } catch(e) { | ||
|  |           console.error("[Service] couldn't start service"); | ||
|  |           console.error(e.stack); | ||
|  |           resolve(null); | ||
|  |           return; | ||
|  |         } | ||
|  |       }, 1); | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   function startServices(services) { | ||
|  |     var promise = PromiseA.resolve(); | ||
|  |     var servicesMap = {}; | ||
|  |      | ||
|  |     services.forEach(function (srv) { | ||
|  |       promise = promise.then(function () { | ||
|  |         return startService(srv).then(function (service) { | ||
|  |           if (!service) { | ||
|  |             // TODO log
 | ||
|  |             return null; | ||
|  |           } | ||
|  |           srv.service = service; | ||
|  |           servicesMap[srv.name] = srv; | ||
|  |         });  | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     return promise.then(function () { | ||
|  |       return servicesMap; | ||
|  |     }); | ||
|  |   } | ||
|  | 
 | ||
|  |   return loadServices().then(startServices); | ||
|  | }; |