NodeJS: обещание или форк для трудоемких (2-5 минут) функций

#javascript #node.js #promise #fork

#javascript #node.js #обещание #форк

Вопрос:

Я столкнулся с вариантом использования в nodejs, где одна из асинхронных функций завершается в течение 2-5 минут. В этой функции есть некоторые ожидаемые асинхронные функции. Код выглядит следующим образом:

 async mainFunc(param1, param2, param3){
    await func1(param1);    //some DB activity
    await func2(param2);    //some SSH acitivity
    await func3(param3);    //some API calls
    ......
    ......
    // removed "return someResu<"
    notify(result);
}
  

mainFunc запускается REST API, и для завершения требуется несколько минут. Однако REST API не ожидает его завершения, поэтому что-то вроде этого (в express)

 app.post('/run', (req, res)=>{
    const { param1, param2, param3 } = req.body;
    mainFunc(param1, param2, param3);
    return res.status(200).send('Initiated');
})
  

Предполагая, что я буду получать несколько клиентских запросов /run . Мой вопрос — должен ли я использовать mainFunc как обещание или я должен разветвлять дочерний процесс, который запускается mainFunc . Я не могу решить, какой подход был бы лучше, учитывая, что mainFunc может занять до 10 минут. Пожалуйста, помогите мне понять плюсы и минусы обоих подходов — Promise и Fork.

Комментарии:

1. Что вам действительно следует делать, так это не иметь маршрутов, выполнение которых занимает 2-5 минут. Вместо этого следуйте шаблону REST и заставьте этот маршрут инициировать все, что должно произойти, а затем ответить 200 и некоторым контентом, который сигнализирует о выполнении действия, чтобы клиент мог время от времени запрашивать результат, вызывая тот же URL, пока ответ не будет равен 200 с полезной нагрузкой результата вместо «выполняется «. И затем вам нужно выяснить, почему на выполнение необходимой вам работы уходит так невероятно много времени: 2-5 минут на запрос к БД — это абсолютно безумно, и предполагает, что ваш SQL нуждается в работе.

2. Предполагая, что все входящие вызовы mainFunc являются правильно асинхронными и не загружают процессор, нет причин создавать дочерний процесс для них.

3. @Mike’Pomax’Camermans «в этом случае даже не заставляйте свое собственное соединение ждать» — какое соединение? «закройте запрос с «ожидающим» ответом» — запрос уже не ожидает mainFunction . Что я недопонимаю в вашем комментарии?

4. Извините, пропустил ту часть, где вы не await используете mainFunc, я видел, что у него есть return оператор, которого у него не должно быть, если вы ничего не делаете с этими данными. Сказав это, если func2 для завершения требуется много времени, действительно важно понять, что на самом деле делает этот код. await предназначен для того, чтобы не блокировать движок JS, поэтому, пока вы не оставляете запрос открытым, этот код уже в основном в порядке.

5. Да: вы не можете отменить их, потому что нет безопасного способа сделать это. Если ваши задачи должны быть отменяемыми, вам придется написать код для безопасного достижения этого; использование fork не делает это более безопасным, оно просто позволяет принудительно завершить процесс, а не просто завершить его. Обновите любой код, который должен быть прерываемым, чтобы вы могли сказать ему прекратить делать то, что он делает, а затем чисто выйти или вернуться (при необходимости).