Я пытаюсь сузить причину этой проблемы и столкнулся с поведением, которого я не ожидал.
Я использую Node v11.8.0 в Ubuntu 18.04.1 LTS.
Если бы я запустил этот скрипт:
const fs = require('fs');
const { promisify } = require('util');
const { spawn, spawnSync, execSync } = require('child_process');
const { O_RDWR } = fs.constants;
const pipePath = "/tmp/myPipe";
let pipeHandle;
let stream;
function pipeListener(data) {
console.log("Pipe data received", data.length);
}
async function setupPipe() {
await promisify(fs.unlink)(pipePath)
.then(function() {}, function(err) {console.warn("Error removing pipe", err);}); // Ignore errors which may happen if the pipe doesn't exist
spawnSync('mkfifo', [pipePath]);
pipeHandle = await promisify(fs.open)(pipePath, O_RDWR); // https://stackoverflow.com/a/53492514/674675
stream = fs.createReadStream(null, {fd: pipeHandle, autoClose: false});
stream.on('data', pipeListener);
stream.on('close', () => {/*console.log("Stream closed");*/});
stream.once('data', () => {
console.log("First data");
});
}
async function teardownPipe() {
stream.removeAllListeners('data');
stream.close();
}
async function reproduceBug() {
let i = 0;
while(i < 50) {
try {
let stat = fs.fstatSync(pipeHandle);
let path = fs.readlinkSync('/proc/self/fd/' + pipeHandle);
console.warn("File", path, "still open after iteration", i);
} catch (ex) {
}
i++;
await setupPipe();
await teardownPipe();
}
setInterval(() => {
// Prevents the process from terminating so that you can inspect the handles with lsof
}, 1000);
}
reproduceBug().then(() => {
console.log("Done");
}, (err) => {
console.error(err);
});
Я бы ожидал увидеть непротиворечивые результаты на каждой итерации цикла.
Но вместо этого я 'Я вижу противоречивые и непредсказуемые результаты:
josh@desktop-01:~$ node ./pipeMre.js
File /tmp/myPipe still open after iteration 9
File /tmp/myPipe still open after iteration 13
File /tmp/myPipe still open after iteration 14
File /tmp/myPipe still open after iteration 27
Done
josh@desktop-01:~$ node ./pipeMre.js
File /tmp/myPipe still open after iteration 7
File /tmp/myPipe still open after iteration 11
File /tmp/myPipe still open after iteration 14
Done
^C
josh@desktop-01:~$ node ./pipeMre.js
File /tmp/myPipe still open after iteration 8
File /tmp/myPipe still open after iteration 29
File /tmp/myPipe still open after iteration 43
File /tmp/myPipe still open after iteration 46
Done
^C
josh@desktop-01:~$ node ./pipeMre.js
File /tmp/myPipe still open after iteration 6
File /tmp/myPipe still open after iteration 7
File /tmp/myPipe still open after iteration 21
File /tmp/myPipe still open after iteration 40
File /tmp/myPipe still open after iteration 48
Done
Это должно произойти?Почему дескриптор файла иногда закрывается, а иногда нет?В моем полном приложении некоторые файловые дескрипторы остаются открытыми до тех пор, пока процесс не будет прерван, что мне не удается воспроизвести в моем минимальном примере.