我有一个程序,该程序可以启动websocket,侦听固定量的消息,将其解析并将其写入磁盘,然后再次关闭websocket。为了提高性能,我使用NodeJS cluster
产生了多个工作进程,这些工作进程同时处理这些消息,其中每个工作进程都打开自己的websocket,并监听传入的消息。
虽然这是单线程的,并且在所有内容都关闭后终止,但是以某种方式在工作线程中执行的相同代码根本不会终止。问题是我无法使用process.exit(0)
,因为我正在向磁盘写入大量数据,因此我需要确保所有异步写入流都能在程序实际退出之前完成其工作。
代码示例:
if (parseInt(command.workers, 10) === 1) {
console.log("Starting Single Process...");
singleProcess();
} else if (cluster.isMaster) {
masterProcess();
} else {
childProcess();
}
function masterProcess() {
for (let i = 0; i < numWorkers; i++) {
const worker = cluster.fork(configQueue.shift());
workers.add(worker);
cluster.on("exit", (exitedWorker, code, signal) => {
// this is never reached
console.log(`worker exited: ${exitedWorker.process.pid}`);
}
}
}
// never terminates
function childProcess() {
console.log(`Worker ${process.pid} started`);
const processor = MyProcessor();
processor.run();
}
// does terminate
function singleProcess() {
const processor = MyProcessor();
processor.run();
}
我用来解析websocket数据的处理器大致如下:
import WebSocket, {Data} from "ws";
import fs, {WriteStream} from "fs";
export class MyProcessor {
private readonly ws: WebSocket;
private readonly writer: WriteStream;
public constructor() {
this.ws = new WebSocket('...');
this.writer = fs.createWriteStream('...');
process.on('SIGTERM', () => {
this.gracefulShutdown();
});
}
public run() {
this.ws.onopen = () => {
this.logger.info("websocket opened");
};
this.ws.onclose = () => {
this.logger.info("websocket closed");
this.writer.close();
};
this.ws.onmessage = (event: { data: Data }) => {
this.parse(message);
};
}
public function close() {
this.gracefulShutdown();
}
private function parse(message) {
// parse message
this.writer.write(parsedMessage);
// if limit reached, exit here
if (...) this.close();
}
private function gracefulShutdown(): void {
this.ws.close();
process.exitCode = 0;
}
}
我还使用了why-is-node-running
包来查找任何打开的处理程序,但没有显示任何内容。我该如何确保以工作者身份运行时该程序正常关闭-而不使用process.exit()
在将所有消息写入磁盘之前都杀死我的WriteStream
?