@mscmls

Как правильно застримить большой поток из exec(...).stdout в ответ сервера?

Есть .json файл размером ~25 мегабайт. Нужно открыть этот файл в поток для чтения, затем запайпить его в ответ сервера (стандартный сервер), перехватить событие pipe ответа сервера, распайпить поток для чтения, вызвать exec(...), запайпить перехваченный поток в stdin, а stdout затем запайпить в ответ сервера, вместо изначального потока.

И в принципе, всё работает, но для неольших буфферов и для файлов не такого большого объёма. Проблема в том, что stdout или сам процесс вызванный через exec - не завершаются, либо завершаются с каким-то рассинхроном с потоком ответа от сервера. В итоге ответ просто бесконечно висит. Ошибок процесса, как и stdin/stdout при этом нет, stderr тоже молчит.

snip
createServer((req, res) => {
    const acceptEncoding = req.headers['accept-encoding']
    if(acceptEncoding){
        const type = acceptEncoding.includes('zstd') ? (
            'zstd'
        ) /*: acceptEncoding.includes('gzip') ? (
            'gzip'
        )*/ : null
        if(type){
            const compressor = (
                type === 'zstd' ? (
                    exec('zstd -10', { encoding: 'buffer' })
                ) /*: type === 'gzip' ? (
                    exec('gzip -5', { encoding: 'buffer' })
                )*/ : null
            )
            if(compressor){
                res.setHeader(
                    'content-encoding', type
                ).once('pipe', source => {
                    source.unpipe(res).pipe(compressor.stdin!)
                    compressor.stdout!.pipe(res)
                    // ?
                    res.on('finish', () => {
                        console.log(2)
                    })
                })
            }
        }
    }
    res.setHeader('content-type', 'text/plain; charset=utf-8')
    createReadStream('./static/large-file.json').pipe(res)
}).listen(4000, () => {
    console.log(1)
})

В чём может быть проблема (если я вообще всё правильно понимаю/делаю) и как её решить?

upd: .json в ответе вообще обрывается. То есть прилетает не целиком. Будто последней чанки не хватает.
  • Вопрос задан
  • 35 просмотров
Решения вопроса 1
@mscmls Автор вопроса
Проблема была в размере буффера (опции exec).
spoiler
exec('zstd -10', { encoding: 'buffer', maxBuffer: 1024 * 4096 }) // x4

maxBuffer : Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated and any output is truncated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы