cluster-rpc.js/master.js

111 rindas
2.9 KiB
JavaScript

2016-09-08 22:23:40 +00:00
'use strict';
function getInstanceMethods(inst) {
var instanceMethods = Object.keys(inst)
.map(function (key) { return 'function' === typeof inst[key] ? key : null; })
.filter(function (key) { return key; })
;
var protoMethods = Object.keys(Object.getPrototypeOf(inst))
.map(function (key) { return 'function' === typeof Object.getPrototypeOf(inst)[key] ? key : null; })
.filter(function (key) { return key; })
;
return instanceMethods.concat(protoMethods);
}
function getMethods(inst, keys) {
if (!keys) {
keys = getInstanceMethods(inst);
}
return keys.filter(function (key) {
if ('function' === typeof inst[key]) {
return true;
}
});
}
2016-09-08 23:48:14 +00:00
function setup(opts) {
2016-09-08 22:23:40 +00:00
var crypto = require('crypto');
var methods = getMethods(opts.instance, opts.methods);
var token = crypto.randomBytes(16).toString('hex');
2016-09-08 23:48:14 +00:00
var inst = opts.instance;
2018-04-21 01:13:48 +00:00
var prefixes = require('./prefixes.js').create(opts); // uses opts.name
2016-09-08 22:23:40 +00:00
2018-04-21 01:13:48 +00:00
opts.master = opts.master || require('./process/master').create(prefixes);
2016-09-08 22:23:40 +00:00
opts.master.on('connection', function (w) {
2018-04-21 01:13:48 +00:00
if (opts.debug) { console.log('[cluster-rpc] [master] worker connected'); }
2016-09-08 22:23:40 +00:00
w.send({
methods: methods
, _token: token
2018-04-21 01:13:48 +00:00
, type: prefixes.init
2016-09-08 22:23:40 +00:00
});
w.on('message', function (cmd) {
2018-04-21 01:13:48 +00:00
if (0 !== (cmd.type||'').indexOf(prefixes.root)) {
2016-09-08 22:23:40 +00:00
//console.log('debug w: got unknown message type');
return;
}
if (token !== cmd._token) {
//console.log('debug w: got bad token');
return;
}
if (!Array.isArray(cmd.args)) {
throw new Error("[Sanity Fail] 'args' should be array of arguments");
}
switch (cmd.type) {
2018-04-21 01:13:48 +00:00
case prefixes.rpc:
2016-09-08 22:23:40 +00:00
cmd.args.push(function callback() {
// args is probably err, data in most cases
var args = Array.prototype.slice.call(arguments);
w.send({
args: args
, id: cmd.id
//, this: this
, _token: token
2018-04-21 01:13:48 +00:00
, type: prefixes.result
2016-09-08 22:23:40 +00:00
});
});
inst[cmd.func].apply(inst, cmd.args);
break;
default:
throw new Error("cluster-ipc UNKNOWN TYPE");
//break;
}
});
});
2016-09-08 23:48:14 +00:00
}
module.exports.create = function (opts) {
2018-04-21 01:13:48 +00:00
if (opts.debug) { console.log('[cluster-rpc] [master] create'); }
2016-09-09 00:25:08 +00:00
var cluster = require('cluster');
2016-09-08 23:48:14 +00:00
var PromiseA = opts.PromiseA || global.Promise || require('bluebird');
var init = false;
2016-09-08 23:49:37 +00:00
opts._promise = PromiseA.resolve(opts.instance);
2016-09-08 23:48:14 +00:00
opts._promise.addWorker = function (w) {
2018-04-21 01:13:48 +00:00
if (opts.debug) { console.log('[cluster-rpc] [master] addWorker wrapper'); }
2016-09-08 23:48:14 +00:00
if (!init) {
init = true;
2016-09-08 23:50:42 +00:00
setup(opts);
2016-09-08 23:48:14 +00:00
}
return opts.master.addWorker(w);
};
2016-09-08 22:23:40 +00:00
2016-09-09 00:25:08 +00:00
if (false !== opts.addOnFork) {
2018-04-21 01:13:48 +00:00
if (opts.debug) { console.log('[cluster-rpc] [master] -- will call addWorker on each fork'); }
2016-09-09 00:25:08 +00:00
cluster.on('fork', opts._promise.addWorker);
}
2016-09-08 22:23:40 +00:00
return opts._promise;
};