I have a Node.js application running an Express server and a worker thread that does something at regular intervals.
When the server is stopped, I need to clean up a connection to an external system that is opened by the worker thread when it starts.
I tried to add a handler on the process for SIGTERM and SIGINT signals, but this does not work, the handler function in the worker thread is not called, it exits immediately with exit code 1 when the parent process receives a SIGINT or SIGTERM, although the parent process also has a handler for these which does get called.
Here is a simple code example to reproduce the problem:
start.js
const http = require("http");
const express = require("express");
const path = require("path");
const { Worker } = require("worker_threads");
let myWorker = null;
process.on("SIGTERM", stop);
process.on("SIGINT", stop);
const app = express();
const server = http.Server(app);
myWorker = new Worker(path.join(__dirname, "./worker.js"));
myWorker.on("exit", code => console.info(`Worker exited with code ${code}`));
server.listen(3000);
function stop() {
console.log("Main process: stop()");
process.exit(0);
}
worker.js
process.on("SIGTERM", stop);
process.on("SIGINT", stop);
setInterval(() => console.log("beep"), 1000);
function stop() {
console.log("Worker process: stop()");
process.exit(0);
}
When I start soWorker.js, I get this output on the console when I interrupt the process with CTRL+C:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker exited with code 1
What I expect to happen is this:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker process: stop()
Worker exited with code 0
I expect the stop
function in the worker thread to be called, so that I can use it to close the connection to the external system, then gracefully exit the worker thread process with return code 0.
Instead, the worker thread exits with code 1, which is the default when a worker thread is stopped.
My question:
How can I execute some clean-up code in my worker thread when the main process is terminated?
Am I on the right track with the approach described above?
I'm mostly spitballin' here, but I think this'll put you on the right track:
add to start.js
process.on('SIGTERM', cleanup);
process.on('SIGINT', cleanup);
myWorker.once('exit', stop);
function cleanup() {
myWorker.postMessage('cleanup');
}
worker.js
const { parentPort } = require('worker_threads');
parentPort.on('message', (value) => {
if (value === 'cleanup') {
cleanup();
//then process.exit(0);
}
});
The following solution should work-
message
event in the worker threadSIGTERM
(or whatever) in the main threadexit
event.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With