NodeJS exec остановится через некоторое время без ошибок - PullRequest
0 голосов
/ 28 ноября 2018

Я использую exec из child_process.

Функция работает нормально, но через 4-5 минут она просто останавливается, без сообщений об ошибках, но скрипт должен работать не менее 24 часов...

Вот код:

import { exec } from 'child_process';

function searchDirectory(dirPath) {
    let lineBuffer = '';

    const cmd = `find ${dirPath} -type f -name "*.txt" | pv -l -L 10 -q`;
    const findData = exec(cmd);

    findData.on('error', err => log.error(err));
    findData.stdout.on('data', data => {
        lineBuffer += data;
        let lines = lineBuffer.split('\n');
        for (var i = 0; i < lines.length - 1; i++) {
            let filepath = lines[i];

            processfile(filepath);
        }
        lineBuffer = lines[lines.length - 1];
    });
    findData.stdout.on('end', () => console.log('finished finding...'));
}

Команда pv замедляет вывод, мне это нужно, поскольку путь, по которому я нахожу, идет по сети и довольно медленный(60 Мбит / с).

Когда я запускаю команду непосредственно в терминале, она работает нормально (я не ждал 24 часа, но я позволил ей полчаса, и она все еще работала).

Функция processfile фактически выполняет асинхронный вызов с axios для отправки некоторых данных на сервер:

    let data = readFileSync(file);
    ...
    axios.post(API_URL, { obj: data }, { proxy: false })
        .then(res => {
            log.info('Successfully saved object : ' + res.data._id);
        })
        .catch(err => {
            log.error(err.response ? err.response.data : err);
        });

Что может привести к остановке сценария?Есть идеи?

Спасибо

1 Ответ

0 голосов
/ 28 ноября 2018

Я обнаружил проблему, использование exec не рекомендуется для больших выходных данных, поскольку он использует буфер ограниченного размера.Вместо этого используйте spawn:

Самое значительное различие между child_process.spawn и child_process.exec заключается в том, что они возвращают - spawn возвращает поток, а exec возвращает буфер.

child_process.spawn возвращает объект с потоками stdout и stderr.Вы можете нажать на поток stdout, чтобы прочитать данные, которые дочерний процесс отправляет обратно в Node.stdout, являющийся потоком, имеет «данные», «конец» и другие события, которые имеют потоки.spawn лучше всего использовать, когда вы хотите, чтобы дочерний процесс возвращал большой объем данных в Node - обработка изображений, чтение двоичных данных и т. д.

child_process.exec возвращает весь буферный вывод дочернего процесса.По умолчанию размер буфера установлен на 200k.Если дочерний процесс возвращает что-то большее, ваша программа завершится сбоем с сообщением об ошибке «Ошибка: превышен maxBuffer».Вы можете решить эту проблему, установив больший размер буфера в параметрах exec.Но вы не должны этого делать, потому что exec не предназначен для процессов, которые возвращают ОГРОМНЫЕ буферы в Node.Вы должны использовать Spawn для этого.Так для чего вы используете exec?Используйте его для запуска программ, которые возвращают статусы результатов, а не данные.

из: https://www.hacksparrow.com/difference-between-spawn-and-exec-of-node-js-child_process.html

...