为什么即使我关闭了所有句柄,node 也会抱怨未关闭的文件描述符?

Why does node complain about unclosed file descriptors even though I'm closing all my handles?

提问人:Ragesh 提问时间:5/25/2023 更新时间:5/25/2023 访问量:69

问:

我有一个异步函数,可以创建一个读取流并将其写入 http 响应,如下所示:

    let handle = await getFile();
    let stream = handle.createReadStream();
    let stat = await handle.stat();
    res.setHeader("content-length", stat.size);
    res.setHeader("content-type", "application/octet");
    res.statusCode = 200;
    stream.pipe(res);
    stream.on('close', () => {
      handle.close();
      res.end();
    });

正如你所看到的,当我的流关闭时,我会关闭句柄,并结束响应以达到很好的效果。然而,我偶尔会看到节点记录这个:

(node:54119) Warning: Closing file descriptor 21 on garbage collection
(Use `node --trace-warnings ...` to show where the warning was created)
(node:54119) [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.

我的 HTTP 响应中没有错误,我已经通过日志验证了我的请求是否被调用。为什么 node 认为我有未关闭的文件描述符?handle.close()

节点 .js 垃圾回收 文件句柄

评论


答:

0赞 Ragesh 5/25/2023 #1

这是因为我的异步函数在流完成写入之前就返回了。我通过用承诺包装它并等待它来修复它:

    let handle = await getFile();
    let stream = handle.createReadStream();
    let stat = await handle.stat();
    res.setHeader("content-length", stat.size);
    res.setHeader("content-type", "application/octet");
    res.statusCode = 200;
    await new Promise<void>((resolve, reject) => {
        stream.pipe(res);
        stream.on('close', () => {
          handle.close();
          res.end();
          resolve();
        });
    });