forked from coolaj86/walnut.js
		
	
		
			
				
	
	
		
			118 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			118 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) {
 | |
|         if (/^\./.test(node)) {
 | |
|           // ignore dot files
 | |
|           return;
 | |
|         }
 | |
|         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);
 | |
| };
 |