2015-12-01 1 views
0

Я выполняю опрос моего узла/экспресс-приложения, когда запущена вычислительная интенсивная функция. Теперь эта функция блокирует узел/выражение как-то от моментального ответа на запросы http-get; вместо этого эти запросы poller ставятся в очередь и возвращают все после завершения вычисления.Node Express Poller Заблокирован вычислительным интенсивным маршрутом

Есть ли модуль или техника, позволяющие узлу «дышать» и отвечать на HTTP-запросы?

Внутри моей основной маршрут

module.exports.parse = (req, res) -> 

# Synchronously Cascading Waterfalls 

    async.waterfall [ 
    (next) -> 
     MyOtherOtherModel.findById req.params.id, (err, data) -> 
     if err 
      next err 
     if !data._id 
      dataError = new Error "Fatal error: Data Result is empty!" 
      next dataError 
     next null, data 

    (data, next) -> 
     fs.readdir 'uploads', (err, files) -> 
     if err 
      next err 
     next null, data, files 

    (data, files, next) -> 

     async.each files, ((file, callback) -> 
     # Do intensive stuff here, parsing, I/O, mapping, etc 

     async.waterfall [ 
      (innerNext) -> 
      MyOtherModel.findByIdAndUpdate data._id, 
       { # data 
       $push: 
        'uploadedFiles': 
        fileName: file 
        length: data.length 
       }, 
       { # options 
       safe: true 
       upsert: true 
       new: true 
       }, (err, dataObjects) -> 
       if err 
        innerNext err 
       innerNext null, dataObjects 
      (dataObjects, innerNext) -> 
      async.each items, ((item, innerCallback) -> 
       MyModel.create myData, (err, result) -> 
       if err 
        innerCallback err 
       innerCallback null 
      ), (err) -> 
       if err 
       innerNext err 
       innerNext null 
     ], (err) -> 
      if err 
      callback err 
      callback null 
    ), (err) -> 
     if err 
      next err 
     # Leave node room to breath, but it isnt working 
     setTimeout (-> 
      next null 
     ), 1000 
    ], (err) -> 
     if err 
     throw Error err # All Errors bubble up to this point 

    # We return immediately, so that express is free to handle poller requests 

    res.status(202).send 
    status: 'OK' 
    error: 'Started Computation.' 
    return 

Мой Poller

module.exports.poll = (req, res) -> 

    # Ask DB and calculate finishedPercentage 

    res.status(206).send 
    status  : 'Partial Content' 
    type  : 'info' 
    error  : percentageFinished + ' % geparsed.' 
    progress  : percentageFinished 

Console Output

Parsing.. 
nextFile.. 
nextFile.. 
nextFile.. 
nextFile.. 
Progress: 100.0 % 
Progress: 100.0 % 
... 

Таким образом, вы можете видеть, что poller каким-то образом поставлен в очередь, пока Node не подумает о времени ответа на HTTP-запросы. Я хочу, чтобы этот прогресс постоянно обновлялся.

+0

Можете ли вы объяснить «вычислительный интенсивный маршрут?» Что именно он делает? – mscdex

+0

Обновлен мой вопрос с кодом. – nottinhill

ответ

1

Одним из решений было бы делегировать задачи (задачи), интенсивные для ЦП, на child process, которые сообщают об обновлениях обновления иногда либо с помощью built-in message passing mechanism узла, либо просто путем записи на stdout и предоставления родительского процесса реле этой информации обратно клиенту.

+0

Thats awesome. Позвольте мне попробовать это завтра, а затем решите дать вам ответ. Уже утвержден. – nottinhill

+0

Возможно ли просто «дублировать» узел для времени выполнения дочернего процесса? Мне нужны все мои модели mongoose, config и т. Д. Для того, чтобы выше задача async была доступна. У вас есть пример? – nottinhill

+0

Существует ['child_process.fork()'] (https://nodejs.org/docs/latest/api/child_process.html#child_process_child_process_fork_modulepath_args_options), но, как отмечается в документации, это не клонирование процесса, как * nix 'fork() '. Однако я думаю, что он все равно может работать для ваших целей. – mscdex