UNPKG

queen-remote

Version:

Rule browsers remotely, remotely

156 lines (123 loc) 4.36 kB
var EventEmitter = require("events").EventEmitter, net = require('net'), its = require('its'); var utils = require('../utils'), MESSAGE_TYPE = require('../protocol.js').QUEEN_MESSAGE_TYPE, createClientWorkforce = require('./clientWorkforce.js'), createClientWorkerProvider = require('./clientWorkerProvider.js'); var create = module.exports = function(socket, queen, options){ var client = new ClientQueen(socket, queen); options = options || {}; if(options.log) client.log = options.log; if(options.debug) client.debug = options.debug; return client; }; var ClientQueen = function(socket, queen){ its.object(socket, "ClientQueen requires a socket"); its.object(queen, "ClientQueen requires a queen instance"); this.emitter = new EventEmitter(); this.on = this.emitter.on.bind(this.emitter); this.removeListener = this.emitter.removeListener.bind(this.emitter); this.socket = socket; this.queen = queen; this.workforces = {}; this.workerProviders = {}; socket.on('data', this.messageHandler.bind(this)); this.workerProviderHandler = this.workerProviderHandler.bind(this); // Emit existing workerProviders queen.workerProviders.forEach(this.workerProviderHandler); // Listen to all future workerProviders queen.on('workerProvider', this.workerProviderHandler); this.kill = utils.once(this.kill.bind(this)); socket.on('close', this.kill); socket.on('end', this.kill); socket.on('error', this.kill); this.sendToSocket([MESSAGE_TYPE['ready']]); }; ClientQueen.prototype.log = utils.noop; ClientQueen.prototype.debug = utils.noop; ClientQueen.prototype.trackWorkerProviders = false; ClientQueen.prototype.kill = function(){ this.sendToSocket = utils.noop; utils.each(this.workforces, function(workforce){ workforce.kill(); }); utils.each(this.workerProviders, function(workerProvider){ workerProvider.kill(); }); this.queen.removeListener('workerProvider', this.workerProviderHandler); this.emitter.emit('dead'); }; ClientQueen.prototype.sendToSocket = function(message){ this.socket.write(message); }; ClientQueen.prototype.messageHandler = function(message){ switch(message[0]){ case MESSAGE_TYPE['workforce message']: this.workforceMessage(message[1], message[2]); break; case MESSAGE_TYPE['create workforce']: this.createWorkforce(message[1], message[2]); break; case MESSAGE_TYPE['track worker provider']: this.trackWorkerProviders = message[1] === true; break; default: this.debug("Unhandled message: " + JSON.stringify(message)); break; } }; ClientQueen.prototype.workforceMessage = function(workforceId, message){ var workforce = this.workforces[workforceId]; if(workforce !== void 0){ workforce(message); } else { this.debug("Workforce doesn't exist: " + JSON.stringify(workforceId) + "\n"); } }; ClientQueen.prototype.workerProviderHandler = function(queenWorkerProvider){ var self = this, onSendToSocket, clientWorkerProvider; onSendToSocket = function(workerProviderMessage){ if(self.trackWorkerProviders){ self.sendToSocket([ MESSAGE_TYPE['worker provider message'], queenWorkerProvider.id, workerProviderMessage ]); } }; clientWorkerProvider = createClientWorkerProvider(queenWorkerProvider, onSendToSocket); this.workerProviders[queenWorkerProvider.id] = clientWorkerProvider; clientWorkerProvider.on('dead', function(){ self.workerProviders[queenWorkerProvider.id].kill(); delete self.workerProviders[queenWorkerProvider.id]; self.sendToSocket([ MESSAGE_TYPE['worker provider dead'], queenWorkerProvider.id ]); }); this.sendToSocket([ MESSAGE_TYPE['create worker provider'], queenWorkerProvider.id, queenWorkerProvider.attributes ]); }; ClientQueen.prototype.createWorkforce = function(remoteId, workforceConfig){ var self = this, workforce, onSendToSocket; onSendToSocket = function(workforceMessage){ self.sendToSocket([ MESSAGE_TYPE['workforce message'], remoteId, workforceMessage ]); }; workforce = createClientWorkforce(this.queen, workforceConfig, onSendToSocket); this.workforces[remoteId] = workforce; workforce.on('dead', function(){ delete self.workforces[remoteId]; }); };