如何防止 Node.js 12 个工作线程立即终止?
How to Prevent a Node.js 12 worker Thread from terminating immediately?
我有一个 Node.js 应用程序 运行 一个 Express 服务器和一个定期执行某些操作的 worker thread。
当服务器停止时,我需要清理工作线程启动时打开的到外部系统的连接。
我试图在进程上为 SIGTERM 和 SIGINT 信号添加一个处理程序,但这不起作用,工作线程中的处理程序函数没有被调用,当父进程收到一个SIGINT 或 SIGTERM,尽管父进程也有一个处理程序 确实 被调用。
这里是重现问题的简单代码示例:
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);
}
当我启动 soWorker.js 时,当我使用 CTRL+C 中断进程时,我在控制台上得到了这个输出:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker exited with code 1
我期望发生的是:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker process: stop()
Worker exited with code 0
我希望工作线程中的stop
函数被调用,这样我就可以用它来关闭与外部系统的连接,然后用return优雅地退出工作线程进程代码 0.
相反,工作线程以代码 1 退出,which is the default when a worker thread is stopped。
我的问题:
如何在主进程终止时在工作线程中执行一些清理代码?
我使用上述方法是否正确?
我主要是在这里吐口水,但我认为这会让你走上正轨:
添加到 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);
}
});
以下解决方案应该有效-
- 在工作线程中订阅主线程
message
事件
- 在主线程中订阅
SIGTERM
(或其他)
- 当您在主线程中捕获到信号时,向工作线程发送一条消息,请求它清理并退出。 ** 暂时不要退出主线程**。
- 在主线程中,通过订阅
exit
事件等待工作线程停止。
- 工作线程停止时,退出主线程。
我有一个 Node.js 应用程序 运行 一个 Express 服务器和一个定期执行某些操作的 worker thread。
当服务器停止时,我需要清理工作线程启动时打开的到外部系统的连接。
我试图在进程上为 SIGTERM 和 SIGINT 信号添加一个处理程序,但这不起作用,工作线程中的处理程序函数没有被调用,当父进程收到一个SIGINT 或 SIGTERM,尽管父进程也有一个处理程序 确实 被调用。
这里是重现问题的简单代码示例:
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);
}
当我启动 soWorker.js 时,当我使用 CTRL+C 中断进程时,我在控制台上得到了这个输出:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker exited with code 1
我期望发生的是:
╰─➤ node start.js
beep
beep
beep
^CMain process: stop()
Worker process: stop()
Worker exited with code 0
我希望工作线程中的stop
函数被调用,这样我就可以用它来关闭与外部系统的连接,然后用return优雅地退出工作线程进程代码 0.
相反,工作线程以代码 1 退出,which is the default when a worker thread is stopped。
我的问题:
如何在主进程终止时在工作线程中执行一些清理代码?
我使用上述方法是否正确?
我主要是在这里吐口水,但我认为这会让你走上正轨:
添加到 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);
}
});
以下解决方案应该有效-
- 在工作线程中订阅主线程
message
事件 - 在主线程中订阅
SIGTERM
(或其他) - 当您在主线程中捕获到信号时,向工作线程发送一条消息,请求它清理并退出。 ** 暂时不要退出主线程**。
- 在主线程中,通过订阅
exit
事件等待工作线程停止。 - 工作线程停止时,退出主线程。