diff --git a/common/websocket-tracker.js b/common/websocket-tracker.js index 1aba8d4..01eb586 100644 --- a/common/websocket-tracker.js +++ b/common/websocket-tracker.js @@ -17,6 +17,12 @@ WebsocketTracker.prototype.closeAll = function() { }); } +WebsocketTracker.prototype.pauseAll = function() { + this.sockets.forEach((value,key) => { + key.pause(); + }); +} + module.exports = function (server) { return new WebsocketTracker(server); } diff --git a/iCubTelemVizServer/iCubTelemVizServer.js b/iCubTelemVizServer/iCubTelemVizServer.js index ce4e752..93e1d39 100644 --- a/iCubTelemVizServer/iCubTelemVizServer.js +++ b/iCubTelemVizServer/iCubTelemVizServer.js @@ -4,9 +4,9 @@ // When the signal comes from the terminal, the generated event doesn't have a 'signal' parameter, // so it appears undefined in the callback body. We worked around this issue by explicitly setting // the 'signal' parameter case by case. -process.once('SIGQUIT', () => {handleTermination('SIGQUIT');}); -process.once('SIGTERM', () => {handleTermination('SIGTERM');}); -process.once('SIGINT', () => {handleTermination('SIGINT');}); +process.once('SIGQUIT', () => {terminationHandler.run('SIGQUIT');}); +process.once('SIGTERM', () => {terminationHandler.run('SIGTERM');}); +process.once('SIGINT', () => {terminationHandler.run('SIGINT');}); // require and setup basic http functionalities var portTelemetryReqOrigin = process.env.PORT_TLM_REQ_ORIGIN || 8080 @@ -175,45 +175,9 @@ var openMctServerHandler = new OpenMctServerHandler(console.log,console.error); var ret = openMctServerHandler.start(); console.log(ret); -function handleTermination(signal) { - console.log('Received '+signal+' ...'); - - /* - * === Closure subset A === - * A.1 - Stop the child Node.js process running the OpenMCT static server. - * A.2 - Stop the Telemetry HTTP server telemServer from accepting new connections. - * A.3 - Stop the Control Console HTTP server consoleServer from accepting new connections. - */ - const closeChildProcessPromise = new Promise(function(resolve,reject) { - ret = openMctServerHandler.stop(signal,resolve,reject); - console.log(ret); - }); - const closeTelemServerPromise = new Promise(function(resolve,reject) { - telemServer.close((error) => { - if (error === undefined) { - resolve('iCub Telemetry Server closed: all sockets closed.'); - } else { - reject(error); - } - }); - console.log('iCub Telemetry Server closing: no further connection requests accepted.'); - }); - const closeConsoleServerPromise = new Promise(function(resolve,reject) { - consoleServer.close((error) => { - if (error === undefined) { - resolve('Control Console Server closed: all sockets closed.'); - } else { - reject(error); - } - }); - console.log('Control Console Server closing: no further incoming requests accepted.'); - }); - Promise.all([closeChildProcessPromise,closeTelemServerPromise,closeConsoleServerPromise]).then( - function(values) { - values.forEach((v) => console.log(v)); - }, - function(error) { - console.error(error.toString()); - } - ); -} +// Handler for a gracious termination +const TerminationHandler = require('./terminationHandler.js'); +var terminationHandler = new TerminationHandler( + openMctServerHandler, + telemServer,telemServerTracker, + consoleServer,consoleServerTracker); diff --git a/iCubTelemVizServer/terminationHandler.js b/iCubTelemVizServer/terminationHandler.js new file mode 100644 index 0000000..f078ca9 --- /dev/null +++ b/iCubTelemVizServer/terminationHandler.js @@ -0,0 +1,67 @@ +"use strict"; + +function TerminationHandler( + openMctServerHandler, + telemServer,telemServerTracker, + consoleServer,consoleServerTracker) { + this.openMctServerHandler = openMctServerHandler; + this.telemServer = telemServer; + this.telemServerTracker = telemServerTracker; + this.consoleServer = consoleServer; + this.consoleServerTracker = consoleServerTracker; +} + +TerminationHandler.prototype.run = function(signal) { + console.log('Received '+signal+' ...'); + this.runSubsetA(signal); +} + +TerminationHandler.prototype.runSubsetA = function (signal) { + /* + * === Closure subset A === + * A.1 - Stop the child Node.js process running the OpenMCT static server. + * A.2 - Stop the Telemetry HTTP server telemServer from accepting new connections. + * A.3 - Stop the Control Console HTTP server consoleServer from accepting new connections. + */ + const closeChildProcessPromise = new Promise(function(resolve,reject) { + let ret = this.openMctServerHandler.stop(signal,resolve,reject); + console.log(ret); + }.bind(this)); + const closeTelemServerPromise = new Promise(function(resolve,reject) { + this.telemServer.close((error) => { + if (error === undefined) { + resolve('iCub Telemetry Server closed: all sockets closed.'); + } else { + reject(error); + } + }); + console.log('iCub Telemetry Server closing: no further connection requests accepted.'); + }.bind(this)); + const closeConsoleServerPromise = new Promise(function(resolve,reject) { + this.consoleServer.close((error) => { + if (error === undefined) { + resolve('Control Console Server closed: all sockets closed.'); + } else { + reject(error); + } + }); + console.log('Control Console Server closing: no further incoming requests accepted.'); + }.bind(this)); + closeChildProcessPromise.then( + function(value) { + console.log(value); + this.runSubsetB(); + }.bind(this), + function(error) { console.error(error.toString()); } + ); +} + +TerminationHandler.prototype.runSubsetB = function() { + /* + * === Closure subset B === + * B.1 - Stop listening to client requests ("subscribe"/"unsubscribe" events) on the existing connections. + */ + this.telemServerTracker.pauseAll(); +} + +module.exports = TerminationHandler;