UNPKG

cluster-service

Version:

Turns your single process code into a fault-resilient multi-process service with built-in REST & CLI support

119 lines (108 loc) 3.23 kB
var cservice = require("../cluster-service"), cluster = require("cluster"), path = require("path"), fs = require("fs"), util = require("util"); module.exports = exports = newWorker; function newWorker(options, cb) { var worker; options = util._extend(util._extend({}, { worker: "./worker.js", count: undefined, restart: true, type: 'user', version: undefined, cwd: undefined, onStop: false }), options); options.ready = false; if ( options.worker.indexOf(".") === 0 || (options.worker.indexOf("//") !== 0 && options.worker.indexOf(":\\") < 0) ) { // resolve if not absolute options.worker = path.resolve(options.worker); } if ( fs.existsSync(options.worker) === false && fs.existsSync(options.worker + ".js") === false ) { if(cb){ cb( "Worker not found: '" + options.worker + "'. Set 'workers' option to proper path." ); } return null; } options.cwd = options.cwd || process.cwd(); options.onReady = cb; var version; if (options.version) { // track workers with version version = cservice.locals.proxy.versions[options.version]; if (!version) { version = { name: options.version, port: options.PROXY_PORT, lastAccess: Date.now(), online: false }; cservice.locals.proxy.versions[options.version] = version; } } worker = cluster.fork(options); worker.cservice = options; worker.on("message", onMessageFromWorker); // track every worker by pid cservice.locals.workerProcesses[worker.process.pid] = worker; return worker; } function onMessageFromWorker(msg) { var worker = this; if (!cservice.msgBus.isValidMessage(msg)) { return; // ignore invalid cluster-service messages } var args, version; switch (msg.cservice.cmd) { case "workerReady": version = cservice.locals.proxy.versions[worker.cservice.version]; if (version) { // if version detected within worker, flag as online version.online = true; // notify proxy workers of version update cservice.proxy.updateProxyWorkers(); } if (worker.cservice.ready === false) { // preserve preference between restarts, etc worker.cservice.ready = true; worker.cservice.onStop = (msg.cservice.onStop === true); if(typeof worker.cservice.onReady === "function"){ worker.cservice.onReady(null, worker); } } break; case "trigger": args = msg.cservice.args; if (args && args.length > 0) { if (msg.cservice.cb === true) { args.splice(1, 0, function(err, result) { // forward response to worker that requested the trigger cservice.msgBus.respondToMessage(msg, worker.process, err, result); }); } else { args.splice(1, 0, null); // no callback necessary } cservice.trigger.apply(cservice, args); } break; case "versionUpdateLastAccess": version = cservice.locals.proxy.versions[msg.cservice.version]; if (version) { // update freshness version.lastAccess = Date.now(); } break; } }