1
0
Fork 0

Finish planning stage of kickstarter?

This commit is contained in:
Max Neunhoeffer 2014-02-01 15:07:48 +01:00
parent 698e240501
commit a0371ec7d9
1 changed files with 76 additions and 59 deletions

View File

@ -1,4 +1,4 @@
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, stupid: true, continue: true */ /*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, stupid: true */
/*global module, require, exports, ArangoAgency, SYS_TEST_PORT */ /*global module, require, exports, ArangoAgency, SYS_TEST_PORT */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -178,7 +178,8 @@ var KickstarterLocalDefaults = {
"agentIntPorts" : [7001], "agentIntPorts" : [7001],
"DBserverPorts" : [8629], "DBserverPorts" : [8629],
"coordinatorPorts" : [8530], "coordinatorPorts" : [8530],
"dispatchers" : [["me", "me"]] "dispatchers" : {"me":{"id":"me", "endpoint":"myself",
"avoidPorts": {}}}
}; };
var KickstarterDistributedDefaults = { var KickstarterDistributedDefaults = {
@ -197,9 +198,18 @@ var KickstarterDistributedDefaults = {
"agentIntPorts" : [7001], "agentIntPorts" : [7001],
"DBserverPorts" : [8629], "DBserverPorts" : [8629],
"coordinatorPorts" : [8530], "coordinatorPorts" : [8530],
"dispatchers" : [ [ "machine1", "tcp://machine1:8529"], "dispatchers" : { "machine1":
[ "machine2", "tcp://machine2:8529"], { "id": "machine1",
[ "machine3", "tcp://machine3:8529"] ] "endpoint": "tcp://machine1:8529",
"avoidPorts": {} },
"machine2":
{ "id": "machine2",
"endpoint": "tcp://machine2:8529",
"avoidPorts": {} },
"machine3":
{ "id": "machine3",
"endpoint": "tcp://machine3:8529",
"avoidPorts": {} } }
}; };
var _ = require("underscore"); var _ = require("underscore");
@ -224,22 +234,18 @@ function copy (o) {
return o; return o;
} }
function PortFinder (list, dispatcherEndpoint) { function PortFinder (list, dispatcher) {
if (!Array.isArray(list)) { if (!Array.isArray(list)) {
throw "need a list as first argument"; throw "need a list as first argument";
} }
if (typeof(dispatcherEndpoint) !== "string") { if (typeof dispatcher !== "object" ||
throw 'need an endpoint or "me" as second argument'; !dispatcher.hasOwnProperty("endpoint") ||
!dispatcher.hasOwnProperty("id") ||
!dispatcher.hasOwnProperty("avoidPorts")) {
throw 'need a dispatcher object as second argument';
} }
this.list = list; this.list = list;
this.map = {}; this.dispatcher = dispatcher;
var i;
for (i in this.list) {
if (this.list.hasOwnProperty(i)) {
this.map[this.list[i]] = true;
}
}
this.dispatcherEndpoint = dispatcherEndpoint;
this.pos = 0; this.pos = 0;
this.port = 0; this.port = 0;
} }
@ -249,27 +255,24 @@ PortFinder.prototype.next = function () {
if (this.pos < this.list.length) { if (this.pos < this.list.length) {
this.port = this.list[this.pos++]; this.port = this.list[this.pos++];
} }
else if (this.port !== 0) { else if (this.port === 0) {
this.port = Math.floor(Math.random()*(65536-1024))+1024;
}
else {
this.port++; this.port++;
if (this.port > 65535) { if (this.port > 65535) {
this.port = 1024; this.port = 1024;
} }
if (this.map.hasOwnProperty(this.port)) {
continue;
}
}
else {
this.port = Math.floor(Math.random()*(65536-1024))+1024;
if (this.map.hasOwnProperty(this.port)) {
continue;
}
} }
// Check that port is available: // Check that port is available:
if (this.dispatcherEndpoint !== "me" || if (!this.dispatcher.avoidPorts.hasOwnProperty(this.port)) {
if (this.dispatcher.endpoint !== "myself" ||
SYS_TEST_PORT("tcp://0.0.0.0:"+this.port)) { SYS_TEST_PORT("tcp://0.0.0.0:"+this.port)) {
this.dispatcher.avoidPorts[this.port] = true; // do not use it again
return this.port; return this.port;
} }
} }
}
}; };
function exchangePort (endpoint, newport) { function exchangePort (endpoint, newport) {
@ -323,13 +326,14 @@ Kickstarter.prototype.makePlan = function() {
// This sets up the plan for the cluster according to the options // This sets up the plan for the cluster according to the options
var config = this.config; var config = this.config;
var dispatchers = config.dispatchers; var dispatchers = this.dispatchers = copy(config.dispatchers);
// If no dispatcher is there, configure a local one (ourselves): // If no dispatcher is there, configure a local one (ourselves):
if (Object.keys(dispatchers).length === 0) { if (Object.keys(dispatchers).length === 0) {
dispatchers.me = "me"; dispatchers.me = { "id": "myself", "endpoint": "myself",
"avoidPorts": {} };
} }
var nrDisp = Object.keys(dispatchers).length; var dispList = Object.keys(dispatchers);
var pf,pf2; // lists of port finder objects var pf,pf2; // lists of port finder objects
var i; var i;
@ -342,13 +346,13 @@ Kickstarter.prototype.makePlan = function() {
for (i = 0; i < config.numberOfAgents; i++) { for (i = 0; i < config.numberOfAgents; i++) {
// Find two ports: // Find two ports:
if (!pf.hasOwnProperty(d)) { if (!pf.hasOwnProperty(d)) {
pf[d] = new PortFinder(config.agentExtPorts, dispatchers[d][1]); pf[d] = new PortFinder(config.agentExtPorts, dispatchers[dispList[d]]);
pf2[d] = new PortFinder(config.agentIntPorts, dispatchers[d][1]); pf2[d] = new PortFinder(config.agentIntPorts, dispatchers[dispList[d]]);
} }
agents.push({"dispatcher":dispatchers[d][0], agents.push({"dispatcher":dispList[d],
"extPort":pf[d].next(), "extPort":pf[d].next(),
"intPort":pf2[d].next()}); "intPort":pf2[d].next()});
if (++d >= dispatchers.length) { if (++d >= dispList.length) {
d = 0; d = 0;
} }
} }
@ -359,15 +363,15 @@ Kickstarter.prototype.makePlan = function() {
d = 0; d = 0;
for (i = 0; i < config.numberOfCoordinators; i++) { for (i = 0; i < config.numberOfCoordinators; i++) {
if (!pf.hasOwnProperty(d)) { if (!pf.hasOwnProperty(d)) {
pf[d] = new PortFinder(config.coordinatorPorts, dispatchers[d][1]); pf[d] = new PortFinder(config.coordinatorPorts, dispatchers[dispList[d]]);
} }
if (!config.coordinatorIDs.hasOwnProperty(i)) { if (!config.coordinatorIDs.hasOwnProperty(i)) {
config.coordinatorIDs[i] = "Coordinator"+i; config.coordinatorIDs[i] = "Coordinator"+i;
} }
coordinators.push({"id":config.coordinatorIDs[i], coordinators.push({"id":config.coordinatorIDs[i],
"dispatcher":dispatchers[d][0], "dispatcher":dispList[d],
"port":pf[d].next()}); "port":pf[d].next()});
if (++d >= dispatchers.length) { if (++d >= dispList.length) {
d = 0; d = 0;
} }
} }
@ -378,15 +382,15 @@ Kickstarter.prototype.makePlan = function() {
d = 0; d = 0;
for (i = 0; i < config.numberOfDBservers; i++) { for (i = 0; i < config.numberOfDBservers; i++) {
if (!pf.hasOwnProperty(d)) { if (!pf.hasOwnProperty(d)) {
pf[d] = new PortFinder(config.DBserverPorts, dispatchers[d][1]); pf[d] = new PortFinder(config.DBserverPorts, dispatchers[dispList[d]]);
} }
if (!config.DBserverIDs.hasOwnProperty(i)) { if (!config.DBserverIDs.hasOwnProperty(i)) {
config.DBserverIDs[i] = "Primary"+i; config.DBserverIDs[i] = "Primary"+i;
} }
DBservers.push({"id":config.DBserverIDs[i], DBservers.push({"id":config.DBserverIDs[i],
"dispatcher":dispatchers[d][0], "dispatcher":dispList[d],
"port":pf[d].next()}); "port":pf[d].next()});
if (++d >= dispatchers.length) { if (++d >= dispList.length) {
d = 0; d = 0;
} }
} }
@ -395,11 +399,9 @@ Kickstarter.prototype.makePlan = function() {
this.coordinators = coordinators; this.coordinators = coordinators;
this.DBservers = DBservers; this.DBservers = DBservers;
this.agents = agents; this.agents = agents;
this.dispatchers = {};
var launchers = {}; var launchers = {};
for (i = 0; i < dispatchers.length; i++) { for (i = 0; i < dispList.length; i++) {
this.dispatchers[dispatchers[i][0]] = dispatchers[i][1]; launchers[dispList[i]] = { "DBservers": [],
launchers[dispatchers[i][0]] = { "DBservers": [],
"Coordinators": [], "Coordinators": [],
"Agents": [] }; "Agents": [] };
} }
@ -424,26 +426,26 @@ Kickstarter.prototype.makePlan = function() {
var s; var s;
for (i = 0; i < DBservers.length; i++) { for (i = 0; i < DBservers.length; i++) {
s = DBservers[i]; s = DBservers[i];
if (s.dispatcher === "me") { if (dispatchers[s.dispatcher].endpoint === "myself") {
dbs[s.id] = map[s.id] dbs[s.id] = map[s.id]
= '"'+exchangePort("tcp://127.0.0.1:0",s.port)+'"'; = '"'+exchangePort("tcp://127.0.0.1:0",s.port)+'"';
} }
else { else {
dbs[s.id] = map[s.id] dbs[s.id] = map[s.id]
= '"'+exchangePort(this.dispatchers[s.dispatcher],s.port)+'"'; = '"'+exchangePort(dispatchers[s.dispatcher].endpoint,s.port)+'"';
} }
launchers[s.dispatcher].DBservers.push(s.id); launchers[s.dispatcher].DBservers.push(s.id);
} }
var coo = tmp.Coordinators = {}; var coo = tmp.Coordinators = {};
for (i = 0; i < coordinators.length; i++) { for (i = 0; i < coordinators.length; i++) {
s = coordinators[i]; s = coordinators[i];
if (s.dispatcher === "me") { if (dispatchers[s.dispatcher].endpoint === "myself") {
coo[s.id] = map[s.id] coo[s.id] = map[s.id]
= '"'+exchangePort("tcp://127.0.0.1:0",s.port)+'"'; = '"'+exchangePort("tcp://127.0.0.1:0",s.port)+'"';
} }
else { else {
coo[s.id] = map[s.id] coo[s.id] = map[s.id]
= '"'+exchangePort(this.dispatchers[s.dispatcher],s.port)+'"'; = '"'+exchangePort(dispatchers[s.dispatcher].endpoint,s.port)+'"';
} }
launchers[s.dispatcher].Coordinators.push(s.id); launchers[s.dispatcher].Coordinators.push(s.id);
} }
@ -487,18 +489,23 @@ Kickstarter.prototype.makePlan = function() {
"intPort": agents[i].intPort }, "intPort": agents[i].intPort },
"peers": [] }; "peers": [] };
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
tmp2.peers.push( exchangePort( this.dispatchers[agents[j].dispatcher], var ep = dispatchers[agents[j].dispatcher].endpoint;
agents[j].intPort ) ); if (ep === "myself") {
ep = "tcp://localhost:0";
}
tmp2.peers.push( exchangePort( ep, agents[j].intPort ) );
} }
tmp.push(tmp2); tmp.push(tmp2);
} }
tmp.push( { "action": "sendConfiguration", tmp.push( { "action": "sendConfiguration",
"agency": exchangePort( this.dispatchers[agents[0].dispatcher], "agency": agents.map(function(a) {
agents[0].extPort ), return exchangePort(dispatchers[a.dispatcher].endpoint,
a.extPort);}),
"data": agencyData } ); "data": agencyData } );
for (i = 0; i < dispatchers.length; i++) { for (i = 0; i < dispList.length; i++) {
tmp.push( { "action": "startLauncher", "dispatcher": dispatchers[i][0], tmp.push( { "action": "startLauncher", "dispatcher": dispList[i],
"name": dispatchers[i][0] } ); "name": dispList[i], "dataPath": config.dataPath,
"logPath": config.logPath } );
} }
}; };
@ -526,6 +533,16 @@ Kickstarter.prototype.isHealthy = function() {
exports.PortFinder = PortFinder; exports.PortFinder = PortFinder;
exports.Kickstarter = Kickstarter; exports.Kickstarter = Kickstarter;
// TODO for kickstarting:
//
// * finden des Pfads zum eigenen Executable in JS
// * etcd in distribution
// * JS function zum Ausführen von Startup-Programmen (lokal u. delegation)
// * REST interface zum Ausführen von Startup-Programmen
// * arangod-Rolle "Launcher" per Kommandozeile
// * REST interface to SYS_TEST_PORT, ev. mit auth
// * Dokumentation
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE // --SECTION-- END-OF-FILE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------