阻止 nodejs 进行垃圾收集/自动关闭文件描述符

Stop nodejs from garbage collection / automatic closing of File Descriptors

考虑一个数据库引擎,它对外部打开的文件进行操作 - 就像 SQLite,除了文件句柄被传递给它的构造函数。我正在为我的应用程序使用这样的设置,但似乎无法弄清楚为什么 NodeJS 在运行 2 秒后坚持关闭文件描述符。我需要那个东西来保持打开状态!

const db = await DB.open(await fs.promises.open('/path/to/db/file', 'r+'));
...
(node:100840) Warning: Closing file descriptor 19 on garbage collection
(Use `node --trace-warnings ...` to show where the warning was created)
(node:100840) [DEP0137] DeprecationWarning: Closing a FileHandle object on garbage collection is deprecated. Please close FileHandle objects explicitly using FileHandle.prototype.close(). In the future, an error will be thrown if a file descriptor is closed during garbage collection.

class DB 在很长一段时间内广泛使用提供的文件描述符,因此关闭它很烦人。在 class 中,我使用 readFilecreateReadStream()readline 模块等方法逐步执行文件的行。我正在将 { autoClose: false, emitClose: false } 传递到我正在使用的任何 read/write 流,但无济于事。

  1. 为什么会这样?
  2. 我该如何阻止它?

谢谢

我怀疑你运行在这个

中使用await遇到了一个邪恶的问题
for await (const line of readline.createInterface({input: file.createReadStream({start: 0, autoClose: false})}))

如果您在 for 循环块中的其他任何地方使用 await(您所在的位置),底层流将触发其所有 data 事件并完成(当您在other await 并且在某些情况下,您的进程甚至在您处理流中的任何 dataline 事件之前就退出了。这是一个真正有缺陷的设计并且已经咬了很多其他。

解决这个问题最安全的方法是根本不使用 asyncIterator,并且自己在 readline 对象的常规事件周围包装一个 promise。