diff --git a/msa/web-ui/docker/start-web-ui.sh b/msa/web-ui/docker/start-web-ui.sh index 804b93da84..575f93c389 100755 --- a/msa/web-ui/docker/start-web-ui.sh +++ b/msa/web-ui/docker/start-web-ui.sh @@ -26,4 +26,5 @@ source "${CONF_FOLDER}/${configfile}" cd ${pkg.installFolder} -exec /bin/sh -c "node server.js" +# This will forward this PID 1 to the node.js and forward SIGTERM for graceful shutdown as well +exec node server.js diff --git a/msa/web-ui/server.ts b/msa/web-ui/server.ts index bc906bb718..2aafe879d1 100644 --- a/msa/web-ui/server.ts +++ b/msa/web-ui/server.ts @@ -22,10 +22,12 @@ import http, { ServerResponse } from 'http'; import httpProxy from 'http-proxy'; import compression from 'compression'; import historyApiFallback from 'connect-history-api-fallback'; +import { Socket } from 'net'; const logger = _logger('main'); let server: http.Server | null; +let connections: Socket[] = []; (async() => { try { @@ -102,34 +104,51 @@ let server: http.Server | null; server.listen(bindPort, bindAddress, () => { logger.info('==> 🌎 Listening on port %s.', bindPort); logger.info('Started ThingsBoard Web UI Microservice.'); - }).on('error', (error) => { + }).on('error', async (error) => { logger.error('Failed to start ThingsBoard Web UI Microservice: %s', error.message); logger.error(error.stack); - exit(-1); + await exit(-1); + }); + + server.on('connection', connection => { + connections.push(connection); + connection.on('close', () => connections = connections.filter(curr => curr !== connection)); }); } catch (e: any) { logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message); logger.error(e.stack); - exit(-1); + await exit(-1); } })(); -process.on('exit', () => { - exit(0); +[`SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => { + process.on(eventType, async () => { + logger.info(`${eventType} signal received`); + await exit(0); + }); +}) + +process.on('exit', async (code: number) => { + logger.info(`ThingsBoard Web UI Microservice has been stopped. Exit code: ${code}.`); }); -function exit(status: number) { +async function exit(status: number) { logger.info('Exiting with status: %d ...', status); if (server) { logger.info('Stopping HTTP Server...'); + connections.forEach(curr => curr.end(() => curr.destroy())); const _server = server; server = null; - _server.close(() => { - logger.info('HTTP Server stopped.'); - process.exit(status); - }); - } else { - process.exit(status); + const serverClosePromise = new Promise( + (resolve, reject) => { + _server.close((err) => { + logger.info('HTTP Server stopped.'); + resolve(); + }); + } + ); + await serverClosePromise; } + process.exit(status); }