load services
This commit is contained in:
parent
96b7c9bb65
commit
78178eb43d
|
@ -78,6 +78,10 @@ cluster.on('online', function (worker) {
|
|||
info.conf.ipcKey = conf.ipcKey;
|
||||
info.conf.memstoreSock = conf.memstoreSock;
|
||||
info.conf.sqlite3Sock = conf.sqlite3Sock;
|
||||
// TODO get this from db config instead
|
||||
var config = require('../config');
|
||||
info.conf.primaryNameserver = config.primaryNameserver;
|
||||
info.conf.nameservers = config.nameservers;
|
||||
worker.send(info);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ module.exports.create = function (conf, deps, app) {
|
|||
|
||||
return new PromiseA(function (resolve, reject) {
|
||||
try {
|
||||
// TODO dynamic requires are a no-no
|
||||
// can we statically generate a require-er? on each install?
|
||||
// module.exports = { {{pkgpath}}: function () { return require({{pkgpath}}) } }
|
||||
// requirer[pkgpath]()
|
||||
route.route = require(pkgpath).create(conf, deps, app);
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
'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);
|
||||
};
|
|
@ -11,6 +11,7 @@ module.exports.create = function (webserver, info, state) {
|
|||
var express = require('express-lazy');
|
||||
var app = express();
|
||||
var apiHandler;
|
||||
var Services;
|
||||
var memstore;
|
||||
var sqlstores = {};
|
||||
var models = {};
|
||||
|
@ -110,6 +111,8 @@ module.exports.create = function (webserver, info, state) {
|
|||
app.use('/', caddyBugfix);
|
||||
|
||||
return PromiseA.all([
|
||||
// TODO security on memstore
|
||||
// TODO memstoreFactory.create
|
||||
cstore.create({
|
||||
sock: info.conf.memstoreSock
|
||||
, connect: info.conf.memstoreSock
|
||||
|
@ -146,14 +149,28 @@ module.exports.create = function (webserver, info, state) {
|
|||
return require('../lib/schemes-config').create(sqlstores.config).then(function (tables) {
|
||||
models.Config = tables;
|
||||
return models.Config.Config.get().then(function (vhostsMap) {
|
||||
|
||||
/*
|
||||
// todo getDomainInfo
|
||||
var utils = require('./utils');
|
||||
results.domains.forEach(function (domain) {
|
||||
utils.getDomainInfo(domain.id);
|
||||
});
|
||||
*/
|
||||
// TODO the core needs to be replacable in one shot
|
||||
// rm -rf /tmp/walnut/; tar xvf -C /tmp/walnut/; mv /srv/walnut /srv/walnut.{{version}}; mv /tmp/walnut /srv/
|
||||
// this means that any packages must be outside, perhaps /srv/walnut/{boot,core,packages}
|
||||
var apiConf = {
|
||||
apppath: '../packages/apps/'
|
||||
, apipath: '../packages/apis/'
|
||||
, servicespath: path.join(__dirname, '..', 'packages', 'services')
|
||||
, vhostsMap: vhostsMap
|
||||
, server: webserver
|
||||
, externalPort: info.conf.externalPort
|
||||
, primaryNameserver: info.conf.primaryNameserver
|
||||
, nameservers: info.conf.nameservers
|
||||
, apiPrefix: '/api'
|
||||
};
|
||||
|
||||
Services = require('./services-loader').create(apiConf, {
|
||||
memstore: memstore
|
||||
, sqlstores: sqlstores
|
||||
, clientSqlFactory: clientFactory
|
||||
, systemSqlFactory: systemFactory
|
||||
, Promise: PromiseA
|
||||
});
|
||||
|
||||
function handleApi(req, res, next) {
|
||||
var myApp;
|
||||
|
@ -183,29 +200,22 @@ module.exports.create = function (webserver, info, state) {
|
|||
return;
|
||||
}
|
||||
|
||||
// apiHandler = require('./vhost-server').create(info.localPort, vhostsdir).create(webserver, app)
|
||||
// apiHandler = require('./vhost-server').create(info.conf.localPort, vhostsdir).create(webserver, app)
|
||||
myApp = express();
|
||||
if (app.get('trust proxy')) {
|
||||
myApp.set('trust proxy', app.get('trust proxy'));
|
||||
}
|
||||
apiHandler = require('./api-server').create(
|
||||
{ apppath: '../packages/apps/'
|
||||
, apipath: '../packages/apis/'
|
||||
, vhostsMap: vhostsMap
|
||||
, server: webserver
|
||||
, externalPort: info.externalPort
|
||||
, apiPrefix: '/api'
|
||||
}
|
||||
, { app: myApp
|
||||
, memstore: memstore
|
||||
, sqlstores: sqlstores
|
||||
, clientSqlFactory: clientFactory
|
||||
, systemSqlFactory: systemFactory
|
||||
//, handlePromise: require('./lib/common').promisableRequest;
|
||||
//, handleRejection: require('./lib/common').rejectableRequest;
|
||||
//, localPort: info.localPort
|
||||
}
|
||||
).api;
|
||||
apiHandler = require('./api-server').create(apiConf, {
|
||||
app: myApp
|
||||
, memstore: memstore
|
||||
, sqlstores: sqlstores
|
||||
, clientSqlFactory: clientFactory
|
||||
, systemSqlFactory: systemFactory
|
||||
//, handlePromise: require('./lib/common').promisableRequest;
|
||||
//, handleRejection: require('./lib/common').rejectableRequest;
|
||||
//, localPort: info.conf.localPort
|
||||
, Promise: PromiseA
|
||||
}, Services).api;
|
||||
|
||||
apiHandler(req, res, next);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
"mime-db": "^1.8.0",
|
||||
"mime-types": "^2.0.10",
|
||||
"ms": "^0.7.0",
|
||||
"native-dns": "^0.7.0",
|
||||
"negotiator": "^0.5.1",
|
||||
"node-pre-gyp": "^0.6.4",
|
||||
"node-uuid": "^1.4.4",
|
||||
|
|
Loading…
Reference in New Issue