Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture SIGINT, SIGTERM, SIGQUIT signals from terminal in both iCubTelemVizServer and openmctStaticServer and close the later #38

Merged
merged 3 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
build*
iCubTelemVizServer/node_modules/*
iCubTelemVizServer/npm-debug.log
iCubTelemVizServer/npm-debug.log*
openmctStaticServer/node_modules/*
openmctStaticServer/npm-debug.log
openmctStaticServer/npm-debug.log*
.idea
.DS_Store

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions iCubTelemVizServer/iCubTelemVizServer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// Server http (non secure)

// Process the termination signals callbacks.
// 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');});

// require and setup basic http functionalities
var portTelemetryReqOrigin = process.env.PORT_TLM_REQ_ORIGIN || 8080
var portTelemetryRespOrigin = process.env.PORT_TLM_RSP_ORIGIN || 8081
Expand Down Expand Up @@ -146,13 +154,13 @@ portRPCserver4sysCmds.onRead(function (cmdNparams) {
});

// Start history and realtime servers
app.listen(portTelemetryRespOrigin, function () {
const telemServer = app.listen(portTelemetryRespOrigin, function () {
console.log('ICubTelemetry History hosted at http://localhost:' + portTelemetryRespOrigin + '/history');
console.log('ICubTelemetry Realtime hosted at ws://localhost:' + portTelemetryRespOrigin + '/realtime');
});

// start the server!
http.listen(3000, function(){
const consoleServer = http.listen(3000, function(){
console.log('listening on http://localhost:3000');
});

Expand All @@ -162,3 +170,8 @@ var openMctServerHandler = new OpenMctServerHandler(console.log);
var ret = openMctServerHandler.start();
console.log(ret.status);
console.log(ret.message);

function handleTermination(signal) {
console.log('Received '+signal+' ...');
openMctServerHandler.stop(signal);
}
26 changes: 17 additions & 9 deletions iCubTelemVizServer/openMctServerHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const path = require('path');
function OpenMctServerHandler(outputCallback) {
// Create a child process spawn for later setting the NVM version and running the server
this.childProcess = require('child_process');
this.processHandle = null;
this.processPID = undefined;
this.outputCallback = outputCallback;
}

Expand All @@ -21,8 +21,8 @@ OpenMctServerHandler.prototype.start = function () {
const embeddedThis = this;

// Start the process
const execPath = path.join(process.cwd(), '..', 'openmctStaticServer');
let npmStart = this.childProcess.spawn('npm', ['start'], {shell: 'bash', cwd: execPath});
const wPath = path.join(process.cwd(), '..', 'openmctStaticServer');
const npmStart = this.childProcess.spawn('sh', ['runModule.sh'], {shell: 'bash', cwd: wPath, stdio: ['pipe','pipe','pipe','ipc']});
nunoguedelha marked this conversation as resolved.
Show resolved Hide resolved

// Set the output callbacks
npmStart.stdout.on('data', function (data) {
Expand All @@ -34,22 +34,30 @@ OpenMctServerHandler.prototype.start = function () {
npmStart.on('error', function (error) {
embeddedThis.outputCallback('[OPEN-MCT STATIC SERVER] error: ' + error.message);
});
npmStart.on('message', function (m) {
embeddedThis.outputCallback('[OPEN-MCT STATIC SERVER] ipc: ' + JSON.stringify(m));
embeddedThis.processPID = m.pid;
});
npmStart.on('close', function (code) {
embeddedThis.processHandle = null;
embeddedThis.processPID = undefined;
embeddedThis.outputCallback('[OPEN-MCT STATIC SERVER] close: ' + code);
});

this.processHandle = npmStart;
return {status: 'OK', message: 'Opem-MCT static server process started.'};
}

OpenMctServerHandler.prototype.stop = function () {
this.processHandle.kill();
return {status: 'PROMISE', message: 'Opem-MCT static server process stopping...'};
OpenMctServerHandler.prototype.stop = function (signal) {
if (this.isOn()) {
process.kill(this.processPID,signal);
console.log('Killing PID %d with signal %s',this.processPID,signal);
return {status: 'WRPLY', message: 'Process OpenMCT Server stopping...'};
} else {
return {status: 'WARNING', message: 'No process OpenMCT Server running...'};
}
}

OpenMctServerHandler.prototype.isOn = function () {
return (this.processHandle != null);
return (this.processPID !== undefined);
}

function spawnSynchInOpenMCTserverPath(childProcess, shellCommand, cmdArgs) {
Expand Down
22 changes: 22 additions & 0 deletions iCubTelemVizServer/websocket-tracker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function WebsocketTracker(server) {
this.server = server;
this.sockets = new Map();
server.on('connection',(socket) => {
console.log('NEW CONNECTION!!');
this.sockets.set(socket,true);
socket.on('close',function() {
console.log('CLOSE CONNECTION');
this.sockets.delete(socket);
}.bind(this));
})
}

WebsocketTracker.prototype.closeAll = function() {
this.sockets.forEach((value,key) => {
key.destroy();
});
}

module.exports = function (server) {
return new WebsocketTracker(server);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions openmctStaticServer/runModule.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
. ${NVM_DIR}/nvm.sh
nvm use v14.17.0
node server.js
nunoguedelha marked this conversation as resolved.
Show resolved Hide resolved

25 changes: 24 additions & 1 deletion openmctStaticServer/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@ app.use('/', staticServer);

var port = process.env.PORT || 8080

app.listen(port, function () {
// Send the process PID back to the parent through the IPC channel
if (process.connected) {
process.send({"pid": process.pid});
}

// Start the server
vizServer = app.listen(port, function () {
console.log('iCub Telemetry Visualizer (Open MCT based) hosted at http://localhost:' + port);
});

// Track the connections
WebsocketTracker = require('../iCubTelemVizServer/websocket-tracker');
const vizServerTracker = new WebsocketTracker(vizServer);

// Handle a clean process termination
function handleTermination(signal) {
console.log('Received '+signal+' ...');
vizServer.close(() => {
console.log('Open-MCT Visualizer Server closed. No further requests accepted. Refreshing the visualizer web page will fail.');
})
vizServerTracker.closeAll();
}

process.prependOnceListener('SIGQUIT', () => {handleTermination('SIGQUIT');});
process.prependOnceListener('SIGTERM', () => {handleTermination('SIGTERM');});
process.prependOnceListener('SIGINT', () => {handleTermination('SIGINT');});