diff --git a/.gitignore b/.gitignore index 6adaeb6..fa7c007 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ npm-debug.log node_modules node_modules/* /node_modules + +.vscode/ +src/amqp_BAK \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3bca8b8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +### Changed +- Reduce usage of `var` +- Use timeout instead of interval for resend messages to clients diff --git a/package.json b/package.json index 223a89e..fbcc4b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "activestack-gateway", - "version": "0.2.5", + "version": "0.2.7", "release_date": "2016-05-03", "description": "Socket server for ActiveStack", "main": "src/main.js", diff --git a/resources/env.default.properties b/resources/env.default.properties index 920c60c..2d5eb51 100644 --- a/resources/env.default.properties +++ b/resources/env.default.properties @@ -33,3 +33,7 @@ gateway.rabbitmq.port=5672 gateway.rabbitmq.login=guest gateway.rabbitmq.password=guest gateway.rabbitmq.durable=false + +frontend.clientMessageResendTimeout=7500 +frontend.clientMessageResendBackoff=1.5 +frontend.clientMessageResendAttempts=7 \ No newline at end of file diff --git a/src/console.js b/src/console.js index cb1fa9b..73faf9b 100644 --- a/src/console.js +++ b/src/console.js @@ -1,19 +1,19 @@ 'use strict'; -var redis = require("redis"); +const redis = require("redis"); function GatewayConsoleApplication(){} module.exports = GatewayConsoleApplication; GatewayConsoleApplication.prototype.run = function(configFile) { configFile = configFile || __dirname + '/../resources/env.default.properties'; - var properties = require('node-properties-parser').readSync(configFile); + const properties = require('node-properties-parser').readSync(configFile); - var gatewayControlQueue = properties['gateway.redis.gatewaycontrolqueue']; + let gatewayControlQueue = properties['gateway.redis.gatewaycontrolqueue']; if (!gatewayControlQueue) gatewayControlQueue = 'gateway'; - var client = redis.createClient(properties['gateway.redis.port'], properties['gateway.redis.host']); + const client = redis.createClient(properties['gateway.redis.port'], properties['gateway.redis.host']); if (properties['gateway.redis.password']) { client.auth(properties['gateway.redis.password'], function (error, result) { if (error) @@ -29,10 +29,8 @@ GatewayConsoleApplication.prototype.run = function(configFile) { process.stdin.resume(); process.stdin.setEncoding('utf8'); - var util = require('util'); process.stdin.on('data', function (text) { - //console.log('received data:', util.inspect(text)); if (text === 'quit\n') { done(); } diff --git a/src/server.js b/src/server.js index 2e1522c..41c5447 100644 --- a/src/server.js +++ b/src/server.js @@ -1,6 +1,6 @@ 'use strict'; -var cluster = require('cluster'), +const cluster = require('cluster'), os = require('os'), redis = require('redis'), fs = require('fs'), @@ -25,7 +25,7 @@ GatewayServer.prototype.inject = function(prefixedLogger, properties, gatewayWor GatewayServer.prototype.start = function(){ - var cpuCount = os.cpus().length; + const cpuCount = os.cpus().length; this.workerCount = this.properties['cluster.workerCount'] || cpuCount / 2 + 1; if(cluster.isMaster){ @@ -52,7 +52,7 @@ GatewayServer.prototype.isMaster = function(){ GatewayServer.prototype.startMaster = function(){ this.setupIPC(); - for (var i = 0; i < this.workerCount; ++i) { + for (let i = 0; i < this.workerCount; ++i) { this.createWorkerProcess(); } }; @@ -62,11 +62,11 @@ GatewayServer.prototype.startMaster = function(){ */ GatewayServer.prototype.setupIPC = function(){ try { - var gatewayControlQueue = this.properties['gateway.redis.gatewaycontrolqueue']; + let gatewayControlQueue = this.properties['gateway.redis.gatewaycontrolqueue']; if (!gatewayControlQueue) gatewayControlQueue = 'gateway'; - var client = redis.createClient(this.properties['gateway.redis.port'], this.properties['gateway.redis.host']); + const client = redis.createClient(this.properties['gateway.redis.port'], this.properties['gateway.redis.host']); if (this.properties['gateway.redis.password']) { client.auth(this.properties['gateway.redis.password'], function(error, result) { if (error) @@ -93,8 +93,8 @@ GatewayServer.prototype.setupIPC = function(){ */ GatewayServer.prototype.onIPCMessage = function (channel, message) { try { - var messageName = message.toLowerCase().trim(); - var params = message.toLowerCase().trim().split(' '); + const messageName = message.toLowerCase().trim(); + const params = message.toLowerCase().trim().split(' '); // TODO: Add workerCount message switch (messageName) { @@ -129,7 +129,7 @@ GatewayServer.prototype.onIPCMessage = function (channel, message) { GatewayServer.prototype.onIPCShutdown = function(params){ this.logger.info('Processing SHUTDOWN message'); this.shuttingDown = true; - var stopCode; + let stopCode; if (params.length > 1) { stopCode = params[1]; } @@ -138,11 +138,11 @@ GatewayServer.prototype.onIPCShutdown = function(params){ this.logger.info('\n************************ INVALID SHUTDOWN CODE RECEIVED!!! ************************\n'); return; } - var stopType = 'immediate'; + let stopType = 'immediate'; if (params.length > 2) { stopType = params[2]; } - var stopTimeout; + let stopTimeout; if (params.length > 3) stopTimeout = parseInt(params[3]); this.stopWorkerProcesses(stopType, stopTimeout); @@ -154,11 +154,11 @@ GatewayServer.prototype.onIPCShutdown = function(params){ */ GatewayServer.prototype.onIPCRestart = function(params){ this.logger.info('Processing RESTART message'); - var restartType = 'immediate'; + let restartType = 'immediate'; if (params.length > 1) { restartType = params[1]; } - var restartInterval; + let restartInterval; if (params.length > 2) restartInterval = parseInt(params[2]); this.restartWorkerProcesses(restartType, restartInterval); @@ -179,7 +179,7 @@ GatewayServer.prototype.onIPCClientCount = function(){ GatewayServer.prototype.onIPCClientMessageResendInterval = function(params){ this.logger.info('Processing CLIENTMESSAGERESENDINTERVAL message'); - var clientMessageResendInterval = this.properties['frontend.clientMessageResendInterval']; + let clientMessageResendInterval = this.properties['frontend.clientMessageResendInterval']; if (params.length > 1) { clientMessageResendInterval = params[1]; } @@ -192,7 +192,7 @@ GatewayServer.prototype.onIPCClientMessageResendInterval = function(params){ */ GatewayServer.prototype.onIPCLogLevel = function(params){ this.logger.info('Processing LOGLEVEL message'); - var logLevel = this.properties['frontend.logLevel']; + let logLevel = this.properties['frontend.logLevel']; if (params.length > 1) { logLevel = params[1]; } @@ -204,7 +204,7 @@ GatewayServer.prototype.startWorker = function(){ }; GatewayServer.prototype.restartWorkerProcesses = function(restartType, restartInterval) { - var oldWorkers = this.workers; + const oldWorkers = this.workers; this.workers = []; this.logger.info('Restarting processes - ' + restartType.toUpperCase()); @@ -212,13 +212,13 @@ GatewayServer.prototype.restartWorkerProcesses = function(restartType, restartIn if (!restartInterval) restartInterval = 500; this.logger.info('Restarting processes at ' + restartInterval + 'ms intervals'); - for(var j=0; j limit * MEGABYTE)) { this.logger.info('Worker exceeded hard ' + type + ' memory limit (' + message.memory[type] + '/' + limit * MEGABYTE + ')!'); @@ -393,7 +393,7 @@ GatewayServer.prototype.onWorkerProcessExit = function(worker, code, signal) { (signal || 'none') + '). Starting replacement...'); clearInterval(worker.watchdog); - for(var i = 0; i < this.workers.length; i++) { + for(let i = 0; i < this.workers.length; i++) { if (this.workers[i] === worker) { this.workers.splice(i, 1); break; @@ -420,7 +420,7 @@ GatewayServer.prototype.createWorkerProcess = function(forceCreate) { } } - var worker = cluster.fork(); + const worker = cluster.fork(); worker.lastHeartbeat = null; worker.watchdog = null; worker.gotFirstHeartbeat = false; diff --git a/src/server_application.js b/src/server_application.js index 8bf5400..3dc9d7f 100644 --- a/src/server_application.js +++ b/src/server_application.js @@ -1,4 +1,4 @@ -var GatewayServer = require('./server'), +const GatewayServer = require('./server'), AppContext = require('injecterooski').AppContext, PrefixedLogger = require('./logging/prefixed_logger'), HttpServerFactory = require('./factory/http_server_factory'), @@ -14,9 +14,9 @@ var GatewayServer = require('./server'), function GatewayServerApplication(){} GatewayServerApplication.prototype.run = function(configFile){ - var appContext = new AppContext(); + const appContext = new AppContext(); - var server = new GatewayServer(); + const server = new GatewayServer(); appContext.register([ server, diff --git a/src/service/client.js b/src/service/client.js index a17fcdc..3117658 100644 --- a/src/service/client.js +++ b/src/service/client.js @@ -1,8 +1,8 @@ 'use strict'; -var Session = require('./session'); -var sys = require('util'); -var EventEmitter = require('events').EventEmitter; +const Session = require('./session'); +const sys = require('util'); +const EventEmitter = require('events').EventEmitter; module.exports = GatewayClient; @@ -31,8 +31,9 @@ function GatewayClient(socket, exchange, rabbitmq, logger, properties, sessionFa this.session = sessionFactory.create(); // Client's session, which also defines client's session ID (reconnectId) + this.awaitingResponseAcksCount = {}; // Holds counts for client message ACK's. this.awaitingResponseAcks = {}; // Holds callback functions for client message ACK's. - this.awaitingResponseAcksInterval = {}; // Message ACK Intervals for client message re-sends. + this.awaitingResponseAcksTimeout = {}; // Message ACK Timeouts for client message re-sends. this.clientQueue = null; // Client RabbitMQ Queue this.disposed = false; @@ -45,25 +46,26 @@ function GatewayClient(socket, exchange, rabbitmq, logger, properties, sessionFa GatewayClient.prototype.dispose = function() { if(this.disposed) return; this.disposed = true; - // Clear Awaiting Response Acks Intervals - if (this.awaitingResponseAcksInterval) { - for(var key in this.awaitingResponseAcksInterval) { - if (this.awaitingResponseAcksInterval.hasOwnProperty(key)) { - var theInterval = this.awaitingResponseAcksInterval[key]; - this.logger.verbose('Clearing interval: ', theInterval); + // Clear Awaiting Response Acks Timeouts + if (this.awaitingResponseAcksTimeout) { + for(const key in this.awaitingResponseAcksTimeout) { + if (this.awaitingResponseAcksTimeout.hasOwnProperty(key)) { + const theTimeout = this.awaitingResponseAcksTimeout[key]; + this.logger.verbose('Clearing timeout: ', theTimeout); try { - clearInterval(theInterval); + clearTimeout(theTimeout); } catch(error) { /* Do nothing on failure here */ } } } - this.awaitingResponseAcksInterval = {}; + this.awaitingResponseAcksTimeout = {}; } // Clear Awaiting Response Acks + this.awaitingResponseAcksCount = {}; this.awaitingResponseAcks = {}; // This sockect is completely closed, need to delete queue. - var disconnectMessage = this.session.populateMessage({ + const disconnectMessage = this.session.populateMessage({ cn: 'com.percero.agents.sync.vo.DisconnectRequest' }); if (disconnectMessage.existingClientId) { @@ -106,7 +108,7 @@ GatewayClient.prototype.init = function() { /** * SpecialMessageHandles - When the client receives a "special" message from the client, this defines how to process/handle * that message. - * - ack Look for the corresponding ACK and acknowledge the message. Clear and remove any interval associated with the message. + * - ack Look for the corresponding ACK and acknowledge the message. Clear and remove any timeout associated with the message. * - connect Register new Auth agent and response queue (RabbitMQ Queue) for the client * - hibernate NOOP * - reconnect Attempt to initialize self using previous client settings, but with new client ID. @@ -124,14 +126,14 @@ GatewayClient.prototype.init = function() { }; GatewayClient.prototype.onHibernate = function(){ - var hibernateMessage = this.session.populateMessage({ + const hibernateMessage = this.session.populateMessage({ cn: 'com.percero.agents.sync.vo.HibernateRequest' }); this.sendToAgent('hibernate', hibernateMessage); } GatewayClient.prototype.onLogout = function(){ - var disconnectAuthMessage = this.session.populateMessage({ + const disconnectAuthMessage = this.session.populateMessage({ cn: 'com.percero.agents.auth.vo.DisconnectRequest' }); this.sendToAgent('disconnectAuth', disconnectAuthMessage); @@ -139,7 +141,7 @@ GatewayClient.prototype.onLogout = function(){ }; GatewayClient.prototype.onAck = function(message) { - var ack = this.awaitingResponseAcks[message.correspondingMessageId]; + const ack = this.awaitingResponseAcks[message.correspondingMessageId]; if (!ack) { // We typically get here when: // We re-sent the message because the client did not ACK in time, but in the meantime the client DID ACK and thus the re-send turned out to be superfluous. @@ -150,15 +152,16 @@ GatewayClient.prototype.onAck = function(message) { delete this.awaitingResponseAcks[message.correspondingMessageId]; } - var theInterval = this.awaitingResponseAcksInterval[message.correspondingMessageId]; - if (theInterval) { + delete this.awaitingResponseAcksCount[message.correspondingMessageId]; + const theTimeout = this.awaitingResponseAcksTimeout[message.correspondingMessageId]; + if (theTimeout) { try { - clearInterval(theInterval); + clearTimeout(theTimeout); } catch(error) { - // If clearing the interval fails for whatever reason, we really don't care and want to move on. + // If clearing the timeout fails for whatever reason, we really don't care and want to move on. } } - delete this.awaitingResponseAcksInterval[message.correspondingMessageId]; + delete this.awaitingResponseAcksTimeout[message.correspondingMessageId]; }; GatewayClient.prototype.onConnect = function() { @@ -188,14 +191,14 @@ GatewayClient.prototype.onReconnect = function(message) { // The reconnectId is an encoded string that should contain all required details to re-establish the // session, including the previous ClientID, which we save and then swap out for the new/current ClientID - var newClientId = this.session.clientId; + const newClientId = this.session.clientId; this.session.load(message.reconnectId); // Decrypts the reconnectId if (!this.session.existingClientIds) { this.session.existingClientIds = []; } // Setup the existing/previous client id(s) - var oldClientId = this.session.clientId; + const oldClientId = this.session.clientId; if (!oldClientId) { logger.error("No previous ClientID on reconnect"); } @@ -207,7 +210,7 @@ GatewayClient.prototype.onReconnect = function(message) { this.onConnect(message); if (this.session.isLoggedIn() && this.session.existingClientId && this.session.existingClientId !== this.session.clientId) { - var reconnectMessage = this.session.populateMessage({ + const reconnectMessage = this.session.populateMessage({ cn: 'com.percero.agents.sync.vo.ReconnectRequest', existingClientId: this.session.existingClientId, existingClientIds: this.session.existingClientIds @@ -230,7 +233,7 @@ GatewayClient.prototype.onReconnect = function(message) { GatewayClient.prototype.routeSpecialMessage = function(type, message) { if (this.specialMessageHandlers[type]) { this.logger.verbose('Handling special message: ' + type + ' / ' + message); - var handler = this.specialMessageHandlers[type]; + const handler = this.specialMessageHandlers[type]; this[handler](message); this.sendSession(); } @@ -247,7 +250,7 @@ GatewayClient.prototype.sendSession = function() { this.session.isDirtyAsync(function(isDirty){ if(isDirty){ this.logger.verbose('Sending session to client.'); - var signedSession = this.session.getSignedSession(); + const signedSession = this.session.getSignedSession(); this.sendToClient('gatewayConnectAck', signedSession); } }.bind(this)); @@ -258,8 +261,8 @@ GatewayClient.prototype.sendSession = function() { * @param response */ GatewayClient.prototype.processResponse = function(response){ - var regex = /^.*\.([^.]*)$/; - var relativeName = response.cn.replace(regex, '$1'); + const regex = /^.*\.([^.]*)$/; + const relativeName = response.cn.replace(regex, '$1'); switch(relativeName){ case 'UserToken': @@ -354,7 +357,7 @@ GatewayClient.prototype.afterLogin = function(){ if(this.session.isLoggedIn()){ // If the session has an existingClientId that is DIFFERENT from its clientId, then issue a ReconnectMessage instead. if (this.session.existingClientId && this.session.existingClientId !== this.session.clientId) { - var reconnectMessage = this.session.populateMessage({ + const reconnectMessage = this.session.populateMessage({ cn: 'com.percero.agents.sync.vo.ReconnectRequest', existingClientId: this.session.existingClientId, existingClientIds: this.session.existingClientIds @@ -364,7 +367,7 @@ GatewayClient.prototype.afterLogin = function(){ this.sendToAgent('reconnect', reconnectMessage); } else { - var connectMessage = this.session.populateMessage({ + const connectMessage = this.session.populateMessage({ cn: 'com.percero.agents.sync.vo.ConnectRequest' }); this.logger.verbose('Connect Message for session client ' + this.session.clientId @@ -424,7 +427,7 @@ GatewayClient.prototype.onClientQueueMessage = function(response, headers, info, this.sendSession(); // Send the updated session to the client. if (response.correspondingMessageId) { - this.setupResendInterval(response, receipt); + this.setupResendTimeout(response, receipt); } else { receipt.acknowledge(); } @@ -433,41 +436,56 @@ GatewayClient.prototype.onClientQueueMessage = function(response, headers, info, }; /** - * Setup an interval to resend the message, at some interval until the client acks + * Setup an timeout to resend the message, at some timeout until the client acks * @param theResponse * @param receipt */ -GatewayClient.prototype.setupResendInterval = function(theResponse, receipt) { +GatewayClient.prototype.setupResendTimeout = function(theResponse, receipt) { // Setup callback function to be used when the 'onAck' function is called for this message this.awaitingResponseAcks[theResponse.correspondingMessageId] = function() { receipt.acknowledge(); }; - this.awaitingResponseAcksInterval[theResponse.correspondingMessageId] = - setInterval(this.resend.bind(this, theResponse), - (this.properties['frontend.clientMessageResendInterval'] || 7500)); + this.awaitingResponseAcksCount[theResponse.correspondingMessageId] = 1; + + // console.log('Setting Ack Timeout: ' + (this.properties['frontend.clientMessageResendInterval'] || this.properties['frontend.clientMessageResendTimeout'] || 7500)); + this.awaitingResponseAcksTimeout[theResponse.correspondingMessageId] = + setTimeout(this.resend.bind(this, theResponse), + (this.properties['frontend.clientMessageResendInterval'] || this.properties['frontend.clientMessageResendTimeout'] || 7500)); }; /** - * Callback function to the interval setup in setupResendInterval. Tries to resend the + * Callback function to the timeout setup in setupResendTimeout. Tries to resend the * message. * * @param theResponse */ GatewayClient.prototype.resend = function(theResponse) { - var ack = this.awaitingResponseAcks[theResponse.correspondingMessageId]; + const ack = this.awaitingResponseAcks[theResponse.correspondingMessageId]; if (ack) { - this.logger.warn('Unacknowledged message being sent again: ', theResponse.correspondingMessageId); - this.sendToClient('push', theResponse); - } - else { - var theInterval = this.awaitingResponseAcksInterval[theResponse.correspondingMessageId]; - if (theInterval) { - this.logger.verbose('Message acknowledged, clearing timer.'); - clearInterval(theInterval); + this.awaitingResponseAcksCount[theResponse.correspondingMessageId]++; + const ackCount = this.awaitingResponseAcksCount[theResponse.correspondingMessageId]; + + if (ackCount <= this.properties['frontend.clientMessageResendAttempts'] || 7) { + this.logger.warn('Unacknowledged message being sent again: ', theResponse.correspondingMessageId); + this.sendToClient('push', theResponse); + console.log('Setting Ack Timeout: ' + ((this.properties['frontend.clientMessageResendInterval'] || this.properties['frontend.clientMessageResendTimeout'] || 7500) * Math.pow((this.properties['frontend.clientMessageResendBackoff'] || 1.5), ackCount))); + this.awaitingResponseAcksTimeout[theResponse.correspondingMessageId] = + setTimeout(this.resend.bind(this, theResponse), + ((this.properties['frontend.clientMessageResendInterval'] || this.properties['frontend.clientMessageResendTimeout'] || 7500) * Math.pow((this.properties['frontend.clientMessageResendBackoff'] || 1.5), ackCount))); + return; } - delete this.awaitingResponseAcksInterval[theResponse.correspondingMessageId]; } + + delete this.awaitingResponseAcksCount[theResponse.correspondingMessageId]; + delete this.awaitingResponseAcks[theResponse.correspondingMessageId]; + + const theTimeout = this.awaitingResponseAcksTimeout[theResponse.correspondingMessageId]; + if (theTimeout) { + this.logger.verbose('Message acknowledged, clearing timeout.'); + clearTimeout(theTimeout); + } + delete this.awaitingResponseAcksTimeout[theResponse.correspondingMessageId]; } /** @@ -475,7 +493,7 @@ GatewayClient.prototype.resend = function(theResponse) { * @param queue */ GatewayClient.prototype.onClientQueueCreation = function(queue) { - var options = { ack: true, prefetchCount: 10 }; + const options = { ack: true, prefetchCount: 10 }; // Setup subscription to the new queue. queue.subscribe(options, this.onClientQueueMessage.bind(this)); diff --git a/src/service/gateway.js b/src/service/gateway.js index 8fa879b..6e0cf6f 100644 --- a/src/service/gateway.js +++ b/src/service/gateway.js @@ -1,8 +1,7 @@ 'use strict'; -var io = require('socket.io'); -var Client = require('./client'); -var RedisStore = require('socket.io/lib/stores/redis'); +const io = require('socket.io'); +const Client = require('./client'); module.exports = Gateway; @@ -73,8 +72,8 @@ Gateway.prototype.initRabbitMQ = function() { Gateway.prototype.onRabbitReady = function () { this.logger.debug("RabbitMQ connection ready"); - var durable = this.properties['gateway.rabbitmq.durable'] == 'true'; - var options = {autoDelete: false, durable: durable, confirm: true}; + const durable = this.properties['gateway.rabbitmq.durable'] == 'true'; + const options = {autoDelete: false, durable: durable, confirm: true}; this.exchange = this.rabbitmq.exchange('', options); this.exchange.on('error', this.gatewayWorker.createErrorHandler('RabbitMQ Exchange')); @@ -86,7 +85,7 @@ Gateway.prototype.onRabbitReady = function () { } Gateway.prototype.onSocketEnd = function (socket, isServerTerminated) { - var client = this.clients[socket.id]; + const client = this.clients[socket.id]; if (client) { client.isServerTerminated = isServerTerminated; } @@ -110,6 +109,13 @@ Gateway.prototype.onSocketEnd = function (socket, isServerTerminated) { data: (!this.sockets || Object.keys(this.sockets).length <= 0) ? 0 : Object.keys(this.sockets).length }); } catch (error) {} + + setTimeout(function(socket, logger) { + try { + // Make sure the socket is disconnected/destroyed. + socket.end(); + } catch(error) {} + },0, socket, this.logger); }; Gateway.prototype.onSocketDisconnect = function (socket, reason, isServerTerminated) { @@ -144,7 +150,7 @@ Gateway.prototype.onSocketConnection = function (socket) { socket.on('disconnect', this.onSocketDisconnect.bind(this, socket)); socket.on('logout', this.onSocketLogout.bind(this, socket)); - var newClient = new Client(socket, this.exchange, this.rabbitmq, this.logger, this.properties, this.sessionFactory); + const newClient = new Client(socket, this.exchange, this.rabbitmq, this.logger, this.properties, this.sessionFactory); this.clients[socket.id] = newClient; newClient.on('dispose', this.onClientDispose.bind(this, socket)); @@ -152,7 +158,7 @@ Gateway.prototype.onSocketConnection = function (socket) { Gateway.prototype.handleError = function(error, source) { - var catchAndWarn = this.gatewayWorker.catchAndWarn; + const catchAndWarn = this.gatewayWorker.catchAndWarn; catchAndWarn('RabbitMQ', function() { this.rabbitmq.end();}.bind(this)); @@ -185,7 +191,7 @@ Gateway.prototype.onShutdown = function(shutdownType) { // RedisClient resists proper error handling :-( Gateway.prototype.attachRedisErrorHandlers = function(type, redis) { - var handler = this.gatewayWorker.createErrorHandler('Redis Store ' + type); + const handler = this.gatewayWorker.createErrorHandler('Redis Store ' + type); redis.on('error', handler); // If the server shuts down we get an "end" instead of an error. diff --git a/src/service/session.js b/src/service/session.js index 0b3f670..34aecf4 100644 --- a/src/service/session.js +++ b/src/service/session.js @@ -1,9 +1,9 @@ 'use strict'; // TODO: Implement rolling session secret. -var MAX_SESSION_AGE = (new Date(0)).setUTCDate(7); // 7 days +const MAX_SESSION_AGE = (new Date(0)).setUTCDate(7); // 7 days -var crypto = require('crypto'); +const crypto = require('crypto'); module.exports = Session; @@ -56,7 +56,7 @@ Session.prototype.clone = function(copy) { }; Session.prototype.signSession = function(encodedSession) { - var hmac = crypto.createHmac('sha512', this.properties['frontend.session_secret'] || 'twothreefour'); + const hmac = crypto.createHmac('sha512', this.properties['frontend.session_secret'] || 'twothreefour'); hmac.update(encodedSession); return hmac.digest('base64'); @@ -71,9 +71,9 @@ Session.prototype.signSession = function(encodedSession) { */ Session.prototype.getSignedSession = function() { this._dirty = false; - var jsonCopy = JSON.stringify(this.clone({ savedAt: Date.now() })); + const jsonCopy = JSON.stringify(this.clone({ savedAt: Date.now() })); - var encodedSession = new Buffer(jsonCopy).toString('base64'); + const encodedSession = new Buffer(jsonCopy).toString('base64'); return (encodedSession + ';' + this.signSession(encodedSession)); }; @@ -99,7 +99,7 @@ Session.prototype.isDirtyAsync = function(callback){ */ Session.prototype.load = function(signedSession) { if (signedSession && (typeof signedSession.split == 'function')) { - var parts = signedSession.split(';'); + const parts = signedSession.split(';'); } else { this.logger.warn('Dropping invalid session: ' + signedSession); return false; @@ -110,15 +110,15 @@ Session.prototype.load = function(signedSession) { return false; } - var encodedSession = parts[0]; - var signature = parts[1]; + const encodedSession = parts[0]; + const signature = parts[1]; if (signature != this.signSession(encodedSession)) { this.logger.warn('Dropping (potentially) tampered session: ' + signedSession); return false; } - var copy = JSON.parse(new Buffer(encodedSession, 'base64').toString()); + const copy = JSON.parse(new Buffer(encodedSession, 'base64').toString()); if (copy.savedAt < Date.now() - MAX_SESSION_AGE) { this.logger.warn('Dropping expired session: ' + signedSession); return false; @@ -133,7 +133,7 @@ Session.prototype.load = function(signedSession) { // Dirty ourselves so the client gets an update with a newer timestamp. this._dirty = true; - var leftovers = Object.keys(copy); + const leftovers = Object.keys(copy); if (leftovers.length > 0) { this.logger.warn('Dropping unexpected session keys ' + JSON.stringify(leftovers) + ': ' + signedSession); diff --git a/src/worker.js b/src/worker.js index c3f7ceb..1afef77 100644 --- a/src/worker.js +++ b/src/worker.js @@ -22,11 +22,11 @@ GatewayWorker.prototype.isExiting = function(){ }; GatewayWorker.prototype.checkMemoryUsage = function () { - var memoryUsage = process.memoryUsage(); - var megabyte = 1024 * 1024; - for (var type in memoryUsage) { - var limit = this.properties['cluster.memoryLimit.' + type]; - var warning = this.properties['cluster.memoryWarning.' + type]; + const memoryUsage = process.memoryUsage(); + const megabyte = 1024 * 1024; + for (let type in memoryUsage) { + const limit = this.properties['cluster.memoryLimit.' + type]; + const warning = this.properties['cluster.memoryWarning.' + type]; if (limit && (memoryUsage[type] > limit * megabyte)) { this.logger.error('Worker exceeded hard ' + type + ' memory limit (' + memoryUsage[type] + '/' + limit * megabyte + ')!'); @@ -53,9 +53,9 @@ GatewayWorker.prototype.sendMessage = function(message) { GatewayWorker.prototype.onMessageStopOrRestart = function(msg){ - var cmd = msg.cmd; - var type = msg.type; - var data = parseInt(msg.data); + const cmd = msg.cmd; + const type = msg.type; + const data = parseInt(msg.data); this.logger.info('server received '+msg.cmd+' message: ' + type); if (type.toLowerCase() === 'on_client_queue_empty') { @@ -86,14 +86,14 @@ GatewayWorker.prototype.onMessageStopOrRestart = function(msg){ GatewayWorker.prototype.onMessageLogLevel = function(msg){ throw new Error('NOT IMPLEMENTED'); - //var logLevel = msg.data; + //const logLevel = msg.data; //this.logger.info('Setting LogLevel to ' + logLevel); //logger.remove(winston.transports.Console); //logger.add(winston.transports.Console, {level: logLevel}); }; GatewayWorker.prototype.onMessageCMSI = function(msg){ - var clientMessageResendInterval = msg.data; + const clientMessageResendInterval = msg.data; this.logger.info('Setting clientMessageResendInterval to ' + clientMessageResendInterval); this.properties['frontend.clientMessageResendInterval'] = clientMessageResendInterval; }; @@ -104,7 +104,7 @@ GatewayWorker.prototype.onMessageClientCount = function(msg){ }; GatewayWorker.prototype.onProcessMessage = function (msg) { - var command = msg.cmd.toLowerCase(); + const command = msg.cmd.toLowerCase(); switch(command){ case 'restart': this.onMessageStopOrRestart(msg);