0

My application is built on Nodejs + Mongodb + amqp. The core module is receiving the the message from amqp, then wrap it into the corresponding message transaction. In the message transaction, save the message information into mongodb and some other logic.

function messageReceiverCallback(msg) {
  try {
    messageHandler(decode(msg));
  } catch (ex) {
  } 
}

function messageHandler(msg) {
  function defaultTransaction() {
  }
  var dispatch = {
    'default': defaultTransaction
  }

  dispatch[MSG.TYPE1] = Msg1Transaction;
  // other message transaction here

  return (dispatch[msg.type] || dispatch['default'])(msg);
}

function Msg1Transaction(msg) {
   // some mongodb operation here...
}

However, when there are several same type messages with different message field value in the queue of amqp, then the messageReceiverCallback will be called, and the Msg1Transaction also be invoked multiple times. As a result, the data saved in the mongodb will be incorrect, because of the asynchronous operation on mongodb which I have ignored. How can I handle it in this case??

I have one idea, add one new transaction queue wrapped with Promise maybe. So the transaction can be processed asynchronously. But I do not how to implement it? could one can help me or some other better solution to solve it?

zangw
  • 43,869
  • 19
  • 177
  • 214

1 Answers1

1

I am not familiar with amqp, but if I understood your problem you want the messageHandler to return when the mongo operation finishes. In this case the correct logic would be:

function messageReceiverCallback(msg) {
   try {
     messageHandler(decode(msg));
    } catch (ex) { ... } 
}

function messageHandler(msg) {
   Msg1Transaction(msg, callbackAfterTransaction);
}

function callbackAfterTransaction(data){
   // update transaction info
}

function Msg1Transaction(msg, callback) {
 // some mongodb operation here...
 Collection.find ({}, 
    function(err, data)
    {
       ...
       callback(data);
    }
}
Pio
  • 4,044
  • 11
  • 46
  • 81
  • What if there are three `Msg1` at the same time, then three `Msg1Transaction` are created. I want to those three transaction processed asynchronously in chain, such as `Promise(Msg1Transaction).then(Msg1Transaction).then(Msg1Transaction)`, How should I do? – zangw Apr 11 '15 at 02:12
  • I am not sure you grasp the idea of asynchrony. So if you want to process events asynchronously then you have **no control** over the order of execution. If you want to process events synchronously then you can do that as well by using some third party library (take a look at [this question](http://stackoverflow.com/questions/6048504/synchronous-request-in-nodejs)). – Pio Apr 13 '15 at 20:59