'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; } }); } module.exports.create = function (opts) { var PromiseA = opts.PromiseA || global.Promise || require('bluebird'); var crypto = require('crypto'); var inst = opts.instance; var methods = getMethods(opts.instance, opts.methods); var token = crypto.randomBytes(16).toString('hex'); var msgPrefix = 'cluster-rpc.' + opts.name; var rpcPrefix = msgPrefix + '.rpc'; var resultPrefix = msgPrefix + '.result'; var initPrefix = msgPrefix + '.init'; opts.master = opts.master || require('./process/master').create(); opts.master.on('connection', function (w) { //console.log('debug w: worker connection'); w.send({ methods: methods , _token: token , type: initPrefix }); w.on('message', function (cmd) { if (0 !== (cmd.type||'').indexOf(msgPrefix)) { //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) { case rpcPrefix: 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 , type: resultPrefix }); }); inst[cmd.func].apply(inst, cmd.args); break; default: throw new Error("cluster-ipc UNKNOWN TYPE"); //break; } }); }); opts._promise = PromiseA.resolve(inst); opts._promise.addWorker = opts.master.addWorker; return opts._promise; };