在NodeJS中可靠地读取FIFO



我正在编写一个与第三方应用程序交互的NodeJS脚本。第三方应用程序将在文件打开期间将数据写入文件。我希望我的NodeJS应用程序能够实时接收这些数据。

我的脚本创建了一个fifo:

child_process.spawnSync('mkfifo', [pipePath]);

然后,它使用child_process.spawn启动第三方应用程序。最后,它从管道中读取。

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY);
let stream = fs.createReadStream(null, {fd: pipeHandle, autoClose: false});
stream.on('data', d => {
console.log(d.length);
});

如果第三方应用程序正常工作,这将非常有效。但是,在某些情况下,第三方应用程序将在不写入文件/FIFO的情况下退出。在这种情况下,我的脚本中的fs.open((调用将永远阻塞。(请参阅GitHub上的相关问题(

为了解决这个问题,我使用了

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);

这可以防止我的脚本在第三方应用程序失败时挂起,但现在"数据"事件永远不会被触发,即使第三方的应用程序工作正常。我想知道用O_NONBLOCK打开FIFO是否不算打开读取?

我不确定解决这个问题的最佳方法是什么。目前,我正在考虑启动第三方应用程序,等待10秒,看看它是否仍在运行,然后打开fifo进行读取,因为如果第三方程序真的要失败,它很可能会很快失败。但这是一个黑客,所以我想知道什么是更好的解决方案。

谢谢!

当然,我一问这个问题就想出来了。

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDWR);

这打开fifo时没有阻塞,因为它同时连接了一个写入程序和一个读取器。一个fifo可以有多个编写器,因此第三方应用程序仍然可以连接而不会出现任何问题。

最新更新