Постановка в очередь заданий на очистку с помощью Bull, Puppeteer, NodeJS и Express

#node.js #express #heroku #redis #puppeteer

#node.js #экспресс #heroku #redis #puppeteer

Вопрос:

Недавно я создал платформу на Heroku для размещения скриптов очистки Puppeteer (Express, Node JS). Все шло отлично, пока выполнение сценариев не стало занимать все больше и больше времени. Согласно документации Heroku, время ожидания запроса превышает 30 секунд, и он завершается с ошибкой.

Обойти это можно с помощью сервера Redis (в частности, с модулем npm Bull).

Я никогда раньше не слышал об очередях, так что это будет возможностью для меня.

Ниже приведен мой текущий код (который работает).

Я проведу вас через весь процесс (тщательно):

  1. Сервер получает POST-запрос от клиента с просьбой запустить этот скрипт, хранящийся в базе данных:
 router.post(
  "/get-data/:id", // route
  ensureAuth, // ensure the person making the request is allowed to make the request in the first place
  fsController.createFile, // creates a .js file where the script will be copied to
  scraperController.getData, // runs the function in the newly created .js file
  csvController.buildCSVAndDeliver // adds that data to a csv file and downloads it
);
  
  1. Файл создается, и в него копируется код из базы данных
 const Script = require("../models/Script");
const fs = require("fs");

exports.createFile = async (req, res, next) => {
  try {
    const script = await Script.findById({ _id: req.params.id });
    let filename = `./scraper/${script._id}.js`;

    // While loop to check if file exists and to append a digit if it does.
    let counter = 0;
    while (fs.existsSync(filename)) {
      filename = `./scraper/${script._id}${counter}.js`;
      counter  ;
    }

    fs.writeFileSync(filename, script.script);
    req.filename = filename;
    next();
  } catch (error) {
    fs.unlink(filename);
    res.send(error, "Please Try Again");
    res.redirect('/dashboard')
  }
};
  
  1. scraperController берет этот файл и выполняет его
 const fs = require("fs");

exports.getData = async (req, res, next) => {
  try {
    let scraper = require(`.${req.filename}`);
    const response = await scraper(req.body);
    req.response = response;
    fs.unlinkSync(req.filename);
    next();
  } catch (error) {
    res.send(error, "Please Try Again");
    fs.unlinkSync(req.filename);
  }
};
  
  1. Наконец, файл CSV загружен
 const fs = require("fs");
const { Parser } = require("json2csv");

exports.buildCSVAndDeliver = async (req, res) => {
  let csvFile = `./csv/${req.params.id}.csv`;

  try {
    const parser = new Parser();
    const csv = parser.parse(req.response);
    fs.writeFileSync(csvFile, csv);
    res.download(csvFile, function () {
      fs.unlinkSync(csvFile);
    });
  } catch (error) {
    console.log(error);
  }
}
  

Теперь, когда вы знаете процесс, куда мне добавить код очереди? Будет ли это вообще работать с этой структурой кода?

Спасибо, и если вам понадобится дополнительная информация от меня, пожалуйста, не стесняйтесь спрашивать.