NodeJS рабочая очередь за героку - PullRequest
0 голосов
/ 30 января 2020

У меня есть приложение nodeJS, где пользователи могут загружать данные для своего магазина. Это форма с большим количеством данных, они могут загружать до 10 изображений (через dropzone), PDF-файлы и множество полей.

В настоящее время я использую грозный (также пробовал многопартийность) для обработки этой операции. В моем form.parse (req) я загружаю все файлы, загружаю данные в firestore и т. Д.

Это работает как очарование локально через localhost (требуется всего около 3 секунд), но, к сожалению, когда я загрузить мое приложение в Heroku, оно требует слишком много времени для обработки (более 30 секунд, поэтому применяется тайм-аут героку). Я мог бы обработать часть загрузки изображения через рабочий процесс с Bull, как предлагает Героку, но моя проблема в том, что я даже не дошел до этой точки, потому что form.parse (req) нужно слишком долго.

Итак, я хотел добавить всю функцию (включая синтаксический анализ формы) в очередь, но, к сожалению, я не могу передать объект "req" в очередь, которая требует огромных усилий. Я также попытался сохранить-привести в соответствие объект req и проанализировать его, чтобы в нем не было никаких круглых объектов, но это не помогает. В form.parse произошли разные ошибки, поэтому грозному нужен «реальный» объект req.

Вот небольшой фрагмент кода моей функции.

function addRestaurant(req, res) {
var oRestaurant = {}
var that = this;

console.log("Function Add-Restaurant")
// var form = new multiparty.Form();
var form = new Formidable();

// res.send(200);
return new Promise((resolve, reject) => {
    //tried to stringify it but formidable needs the original req object.
    //var jsonReq = stringify(req, null, 2);
    //jsonReq = JSON.parse(jsonReq);
    // console.log(jsonReq);
    var { io } = require("../server.js")
    io.on('connection', function (socket) {
        console.log('CONNECTED');
        socket.join(req.session.id);
    });

    form.on('progress', function (bytesReceived, bytesExpected) {
        console.log(bytesReceived + " / " + bytesExpected)
        io.in(req.session.id).emit('uploadProgress', (bytesReceived * 100) / bytesExpected);
    });
    form.on('aborted', function (err) {
        console.log(err);
        reject(err);
    });
    form.parse(jsonReq, function (err, fields, files) {
        try {
            console.log("Form parsed!");
            console.log(err);
            if (err) {
                reject(err);
                return;
            }
            console.log(fields);
            if (!fields || !fields.formfields) {
                reject("Es ist ein interner Fehler aufgetreten. Bitte versuchen Sie es später erneut.");
                return;
            }

            if (fields && fields.formfields && fields.formfields.length === 0) {
                reject("Es ist ein interner Fehler aufgetreten. Bitte versuchen Sie es später erneut.");
                return;
            }

            console.log("Adding to queue")

            //in this queue is the process to upload the files to google storage and add the data to firestore; never get to this point, because form.parse needs too long!
            restaurantQueue.add({
                fields: fields,
                files: files,
                account_type: req.session.userFirestore.account_type,
                uid: req.session.userAuth.uid
            });

            restaurantQueue.on('completed', function (job, result) {
                console.log("Restaurant added complete");
                if (req.session.restaurants) {
                    req.session.restaurants.push({
                        id: result.id,
                        data: result.data
                    })
                }
                else {
                    req.session.restaurants = [{
                        id: result.id,
                        data: result.data
                    }];
                }
                console.log("emit event finish uploading");
                io.in(req.session.id).emit('finishUploading');
                resolve();
            });

            restaurantQueue.on('failed', function (error) {
                reject(error.failedReason);
            })


           ....

Так что мне нужно обработать форма разбирается в рабочей задаче, но не может передать ей объект запроса. Вы знаете, как я могу решить мою проблему? Есть ли какая-либо другая возможность, как я могу выполнить весь процесс в фоновом режиме, не имея проблемы с тайм-аутом запроса heroku?

Я также попытался сначала отправить ответ, а затем обработать анализ формы, но Я получаю следующую ошибку: «Запрос сервера прерван» с «sock = backend»; Причина в том, что я отправляю ответ, но запрос не может быть завершен, поэтому он пытается снова и снова ...

...