UNPKG

wotcs-api-system

Version:

Base system used to build WoTcs clans and players API

150 lines (129 loc) 5.1 kB
var Eventer = require('../base/eventer'); var cluster = require('cluster'); var LocalWorker = require('./local_worker'); var ClusterWorker = require('./cluster_worker'); var ServerWorker = require('./server_worker'); var ClientWorker = require('./client_worker'); var _ = require('underscore'); module.exports = Eventer.extend({ init: function(queue, rootDir, clientFile, config) { this.config = config; this.localWorker = false; this.clientFile = clientFile; this.rootDir = rootDir; this.workers = {}; this.workerCounter = 0; this.queue = queue; this.propagateEvents('queue'); this.baseConfig = config.configs; }, setModels: function(models){ this.models = models; _.each(this.workers, function(worker) { if(worker.type == 'local' || worker.type == 'client'){ worker.setModels(models); } }); }, forAll: function(callback){ _.each(this.workers, function(worker, ID){ callback(worker, ID); }); }, getConfigs: function() { return this.baseConfig; }, setConfigByType: function(type, config) { this.baseConfig[type] = config; _.each(this.workers, function(worker, ID){ var wType = worker.type == 'cluster' ? 'local' : worker.type; if(wType == type){ worker.execute('setConfig',config,function(){}); } }); return this.baseConfig; }, addWorker: function(file) { var self = this; var ID = this.workerCounter++; var worker = this.localWorker ? new ClusterWorker(file, cluster.fork()) : new LocalWorker(file, this.rootDir); if(!this.localWorker){ this.localWorker = worker; }else{ worker.realWorker.on('disconnect', function(){ delete self.workers[ID]; self.emit('workers.remove-worker',{type: 'local', workers: self.getWorkersByType(), ID:ID}, true); self.addWorker(file); }); } this.setupWorker(worker, ID, 'local'); this.workers[ID] = worker; this.emit('workers.add-worker',{type: 'local', workers: this.getWorkersByType()}, true); this.propagateEvents('workers', ID); }, getWorkersByType: function() { var ret = {local: [], server: [], client: []}; _(this.workers).each(function(worker, ID){ var type = worker.type; if(type == 'cluster'){type='local';} ret[type].push(ID); }); return ret; }, addServerWorker: function(ws, options) { var ID = this.workerCounter++; var worker = new ServerWorker(ws, options); this.setupWorker(worker, ID, 'server'); this.workers[ID] = worker; this.emit('workers.add-worker',{type: 'server', workers: this.getWorkersByType()}, true); var self = this; ws.on('close', function() { console.log('Server worker disconnected'); delete self.workers[ID]; self.emit('workers.remove-worker',{type: 'server', workers: self.getWorkersByType(), ID:ID}, true); }); this.propagateEvents('workers', ID); }, addClientWorker: function(ws, options) { if(!options || options.version != this.config.version){ ws.close(1000, 'version'); return; } var count = this.getWorkersByType().client.length; if(this.config.clientLimit <= count){ ws.close(1000, 'client-limit'); return; } var ID = this.workerCounter++; var worker = new ClientWorker(ws, this.clientFile, this.rootDir, options); this.setupWorker(worker, ID, 'client'); this.workers[ID] = worker; this.emit('workers.add-worker',{type: 'client', workers: this.getWorkersByType()}, true); var self = this; ws.on('close', function() { console.log('Client worker disconnected'); self.workers[ID].close(); delete self.workers[ID]; self.emit('workers.remove-worker',{type: 'client', workers: self.getWorkersByType(), ID:ID}, true); }); this.propagateEvents('workers', ID); if(this.models){ worker.setModels(this.models); } }, setupWorker: function(worker, ID, type) { var self = this; worker.setConfig(this.baseConfig[type]); worker.on('ready', function(event, options) { self.queue.getFromQueue(function(task){ worker.setTask(task); }, ID, options); }); worker.on('finish-task', function(event, ID, data){ self.queue.confirmSuccess(ID, data); }); worker.on('fail-task', function(event, ID, data){ self.queue.reportFail(ID, data); }); } });