2015-07-20 2 views
0

Я создаю социальное сообщество, где пользователь получает вознаграждение, если кто-то упрекает/разделяет его/ее ответы. Я также отправляю уведомление пользователю, когда его/ее ответ имеет какое-то взаимодействие.Поток/шаблон для сложных вызовов в node.js

Я объяснил поток, хотя комментарии в следующем коде. Функция post_event подвергается воздействию API, и поток начинается оттуда.

var answerController = function(){ 
    Emitter.call(this); 
    var self = this; 
    var continueWith = null; 

    var push_event = function(event, answerId, likerId, callback){ 

     // check for data and prepare a bacth of queries 
     // has to be done like this coz mongoose doesn't (yet) support nModified, nMatched for update 
     var batch = Answer.collection.initializeOrderedBulkOp(); 
     batch.find(query).upsert().updateOne(update); 
     batch.execute(function(err,result) { 
      if(err){ 
       return callback(err); 
      }else{ 
       return callback(null, result.nModified); 
      } 
     }); 
    }; 


    // exposed as an API call for yo/share/view 
    // calls push_event 
    var post_event = function(req,res, next){ 

      //check for data in incoming request and pass it forward 

      push_event(event,answerId, likerId, function(err, num_updated_docs){ 
       if(err){ 
        return errors.api_error({code: 500, message: err, res: res, next: next}); 
       }else{ 
        if(num_updated_docs){ 
         // create the calculateScore_args variable 
         self.emit('calculateScore',calculateScore_args); 
         res.status(200).send({message : 'success'}).end(); 
        }else{ 
         return errors.api_error({code: 401, message: 'event already exists for user', res: res, next: next}); 
        } 
       } 
      }); 

    }; 


    var score = function(args){ 

     var asyncTasks = []; 
     asyncTasks.push(function(cb){ 
      //update user's score 
      // this is a cpu intensive function (does a small matrix multiplication) 
     }) 

     asyncTasks.push(function(cb){ 
      //update answer's score (user's score is a function of various answers) 
      // another CPU intensive call, calculates confidence interval ---> score 
     }) 

     async.parallel(asyncTasks, function(err, results){ 
      self.emit('notify', notifyData); 
      }) 

    }; 

    function notify(args){ 
     // calls another controller which notifies the user(GCM) and inserts the notification into the DB 
     notification.AnswerEvent(args); 

    } 

    self.on('calculateScore', score); 
    self.on('notify',notify); 

    return { 
     post_event : post_event 
    } 
}; 

Вопрос: Я хотел бы знать, если это возможно шаблон для системы, которая будет получать около 100-200 REQ/сек. Было бы здорово, если бы кто-нибудь мог посоветовать мне другие паттеры (например, очередь сообщений). Кроме того, что является лучшим способом для отладки кода эмиттера событий.

Благодаря

+0

Я измерил время блокировки eventloop с блокировкой (npm) и получил среднее время блокировки 30-40 мс в большинстве вызовов по 1 req/sec. Это время не растет линейно с увеличением количества запросов. Но призыв обновить рейтинг пользователя блокирует цикл около 300-400 мс. Звонок для оценки пользователей - это в основном функция, которая находит пользователя, пересчитывает счет (простой calc) и сохраняет его обратно. Любая идея, почему это может произойти? –

ответ

1

Скользящие ресурсоемкие код из веб-сервера является первым и главным образом для предотвращения блокировки.

Задача очереди - это очень простой способ достичь этого. С Ruby я использовал https://github.com/resque/resque с довольно большим успехом в прошлом.

Узел порта, такой как https://github.com/taskrabbit/node-resque, может быть уместным для ваших нужд. Вы в основном создаете задание, ставите его в очередь и разворачиваете некоторых работников, чтобы разжечь требуемую работу.

+0

Я отслеживаю время события блока эмиттера, и я не уверен, что квалифицируется как интенсивная работа процессора (с точки зрения блокировки EE). какие бывают хорошие варианты использования для использования фонового процессора обработки, такого как resque –

+0

Все, что в node.js, которое не является вводом/выводом, является «интенсивным» процессором для каждого ... хотя это относительно, и, очевидно, порядки величины важный. Такие вещи, как сортировки, поисковые запросы и алгоритмы, как правило, связаны с ЦП. Чем сложнее или «дороже», тем длиннее «блок». Подумайте о том, чтобы попытаться вычислить большой премьер или фибоначчи, например. Это потребует времени, а также является синхронным блоком кода. – snozza

Смежные вопросы