Отчет о прогрессе загрузки из node.js

Я пишу небольшое приложение node.js, которое получает составную часть POST из формы HTML и передает входящие данные в Amazon S3. Грозный модуль обеспечивает многоэлементный разбор, выставляя каждую часть как узел Stream. Модуль knox обрабатывает PUT на s3.

var form = new formidable.IncomingForm()
 ,  s3   = knox.createClient(conf);

form.onPart = function(part) {
    var put = s3.putStream(part, filename, headers, handleResponse);
    put.on('progress', handleProgress);
};

form.parse(req);

Я сообщаю о ходе загрузки клиенту браузера через http://socket.io/, но мне трудно получить эти цифры, чтобы отразить реальный прогресс узла в загрузке s3.

Когда загрузка из браузера в узел происходит практически мгновенно, как это происходит, когда процесс узла выполняется в локальной сети, индикатор прогресса сразу достигает 100%. Если файл большой, т. Е. 300 МБ, индикатор прогресса растет медленно, но все же быстрее, чем позволяет наша пропускная способность восходящего канала. После достижения 100% прогресса клиент зависает, ожидая завершения загрузки s3.

я знаю putStream внутренне использует метод Node stream.pipe, но я не понимаю, как это работает на самом деле. Я предполагаю, что узел поглощает входящие данные так быстро, как только может, выбрасывая их в память. Если поток записи может обрабатывать данные достаточно быстро, в памяти сразу сохраняется небольшое количество данных, поскольку они могут быть записаны и отброшены. Если поток записи медленный, как и здесь, нам, вероятно, придется хранить все эти входящие данные в памяти, пока они не будут записаны. Так как мы слушаем data события в потоке чтения, чтобы отразить прогресс, в итоге мы сообщаем о том, что загрузка идет быстрее, чем она есть на самом деле.

Мое понимание этой проблемы близко к цели? Как я могу пойти исправить это? Нужно ли мне опускаться write, drain а также pause?

1 ответ

Решение

Ваша проблема в том, что stream.pause не реализован наpart, который является очень простым потоком чтения выходных данных из многочастного анализатора форм.

Knox инструктирует s3-запрос генерировать события "progress" всякий раз, когда деталь передает "данные". Однако так как part Поток игнорирует паузу, события прогресса генерируются так же быстро, как данные формы загружаются и анализируются.

Грозный formоднако знает, как pause а также resume (он передает вызовы на запрос, который анализирует).

Примерно так должно решить вашу проблему:

form.onPart = function(part) {

    // once pause is implemented, the part will be able to throttle the speed
    // of the incoming request
    part.pause = function() {
      form.pause();
    };

    // resume is the counterpart to pause, and will fire after the `put` emits
    // "drain", letting us know that it's ok to start emitting "data" again
    part.resume = function() {
      form.resume();
    };

    var put = s3.putStream(part, filename, headers, handleResponse);
    put.on('progress', handleProgress);
};
Другие вопросы по тегам