Отчет о прогрессе загрузки из 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);
};