Add SIGTERM listener on application start

As reported by issue #2100, the supervisor was not correctly reacting to
`SIGTERM` sent by the engine when terminating the process (for instance
before a reboot). This would lead to the supervisor requiring an
additional 10 seconds to terminate (after which the engine will send a
`SIGKILL`).

The reason for this is explained by the following info coming from Node

> Node.js was not designed to run as PID 1 which leads to unexpected behaviour when running inside of Docker. For example, a Node.js process running as PID 1 will not respond to `SIGINT` (`CTRL-C`) and similar signals. [reference](https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals)

On internal testing, it was discovered that simply adding a listener for
the signal on the Node process was enough to handle the signal, even
when the process runs as PID 1.

This adds a listener for `SIGTERM` before starting the supervisor main
loop.

Closes: #2100
Change-type: patch
This commit is contained in:
Felipe Lalanne 2023-01-30 11:47:59 -03:00
parent f663e38697
commit 6683bca07d

View File

@ -53,7 +53,7 @@ interface DnsLookupOpts {
* and on openBalena setups, this extra code will perform
* the lookup instead of passing it to the built-in
* function.
================================================== */
================================================== */
if (name && name.endsWith('.local')) {
// determine which resolvers to use...
const getResolvers = () => {
@ -123,6 +123,17 @@ interface DnsLookupOpts {
import '@balena/happy-eyeballs/eye-patch';
import Supervisor from './supervisor';
import * as process from 'process';
import log from './lib/supervisor-console';
// Register signal handlers before starting the supervisor service
process.on('SIGTERM', () => {
log.info('Received SIGTERM. Exiting.');
// This is standard exit code to indicate a graceful shutdown
// it equals 128 + 15 (the signal code)
process.exit(143);
});
const supervisor = new Supervisor();
supervisor.init();