NodeJS иногда не удается закрыть файл после уничтожения потока чтения - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь сузить причину этой проблемы и столкнулся с поведением, которого я не ожидал.

Я использую 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

Это должно произойти?Почему дескриптор файла иногда закрывается, а иногда нет?В моем полном приложении некоторые файловые дескрипторы остаются открытыми до тех пор, пока процесс не будет прерван, что мне не удается воспроизвести в моем минимальном примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...