0

Using WebSocket I receive updates which i want to store in a mongodb database. Each time there is an update an event with data is emitted. The data is an array of updates, which need to be processed one by one before putting them in the database. Sometimes, a new update is received before the old update is processed. When this happens, only a part of the old update is processed and saved and the function starts processing the new data.

Is there a way to run multiple instances of this function, so that starting a new function with new data doesn't stop the processing of the old data?

eventBTRX.on('marketUpdate', function(data) {
 data.Sells.forEach(function(askChange) {
  console.log(askChange);
  switch (askChange.Type) {
   case 0:
    delete askChange.Type
    var askNew = {
     Quantity: askChange.Quantity,
     Rate: askChange.Rate,
     Type: 'ask',
     Exchange: 'BTRX'
    }
    dbo.collection(colName).insertOne(askNew, function(err, result) {
     if (err) console.log(err);
    });
    break;
   case 1:
    delete askChange.Type
    askChange.Type = 'ask';
    askChange.Exchange = 'BTRX';
    var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
    dbo.collection(colName).deleteOne(deleteQuery, function(err, result) {
     if (err) console.log(err);
    });
    break;
   case 2:
    delete askChange.Type
    askChange.Type = 'ask';
    askChange.Exchange = 'BTRX';
    var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
    var newValue = { $set: {Quantity: askChange.Quantity} };
    dbo.collection(colName).updateOne(updateQuery, newValue, function(err, result) {
     if (err) console.log(err);
    });
    break;
   default:
    console.log('Error in update type.')
  }
 });
Alex
  • 1
  • 1
  • 2
    Starting a new one does not stop the previous one. You will need to show us the actual code inside the `.forEach()` loop for us to see what's wrong and make a specific code suggestion. That's where the code needs to be modified. – jfriend00 Jan 21 '18 at 01:59
  • @jfriend00 thank you. I’ve added the actual code now. – Alex Jan 21 '18 at 02:31

1 Answers1

0

If you just want to make sure that the items from one particular message are inserted in the order they appear in the data.Sells array, then you can use async/await and the promise interface for your database like this:

eventBTRX.on('marketUpdate', async function(data) {
    for (let askChange of data.Sells) {
        console.log(askChange);
        switch (askChange.Type) {
            case 0:
                delete askChange.Type
                var askNew = {
                    Quantity: askChange.Quantity,
                    Rate: askChange.Rate,
                    Type: 'ask',
                    Exchange: 'BTRX'
                }
                await dbo.collection(colName).insertOne(askNew).catch(console.log);
                break;
            case 1:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                await dbo.collection(colName).deleteOne(deleteQuery).catch(console.log)
                break;
            case 2:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                var newValue = { $set: {Quantity: askChange.Quantity} };
                await dbo.collection(colName).updateOne(updateQuery, newValue).catch(console.log);
                break;
            default:
                console.log('Error in update type.')
        }
    }
});

If you further want to make sure that all the items from one marketUpdate message are inserted before another one, then you probably need to create a queue like this:

const marketUpdateQueue = [];

eventBTRX.on('marketUpdate', async function(data) {
    // put all .Sells items in the queue in order
    markedUpdateQueue.push(...data.map(item => item.Sells));
    // if we're already processing an item in the queue, then let it get processed first
    if (marketUpdateQueue.length > 1) {
        return;
    }
    // keep processing queue items until there are no more
    while (marketUpdateQueue.length) {
        let askChange = marketUpdateQueue[0];
        console.log(askChange);
        switch (askChange.Type) {
            case 0:
                delete askChange.Type
                var askNew = {
                    Quantity: askChange.Quantity,
                    Rate: askChange.Rate,
                    Type: 'ask',
                    Exchange: 'BTRX'
                }
                await dbo.collection(colName).insertOne(askNew).catch(console.log);
                break;
            case 1:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var deleteQuery = {Exchange: bidChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                await dbo.collection(colName).deleteOne(deleteQuery).catch(console.log);
                break;
            case 2:
                delete askChange.Type
                askChange.Type = 'ask';
                askChange.Exchange = 'BTRX';
                var updateQuery = {Exchange: askChange.Exchange, Rate: askChange.Rate, Type: askChange.Type};
                var newValue = { $set: {Quantity: askChange.Quantity} };
                await dbo.collection(colName).updateOne(updateQuery, newValue).catch(console.log);
                break;
            default:
                console.log('Error in update type.')
        }
        // remove the item we just processed
        marketUpdateData.shift();
    }
});

Note: Both of these approaches need an error handling strategy (not sure what exactly you want to do if there's a DB error). The code in your original question just logged and ignored the error so that's what this code does also.

jfriend00
  • 683,504
  • 96
  • 985
  • 979