skip to Main Content

I have to keep track of three collection names for three MongoDB collection.
One to insert a json data from an API. The second to consume the data in my own API (this is necessary because I have to avoid the calls restrictions to the API provider). And the third to drop the "old" collection. And this will be repeating every 5 seconds endless. If the following code stay together in one file is no problem, but I have to separate them in 3 different files/modules. My question is what approach is the right one to make it work in NodeJS and to keep the names consistently? At this point, when I run the code the getLetter() it just start over and return the same object every iteration. Here the most important part of code as pseudo code. If you have some experience please help. Thank you!

getLetter.js utils file

// return each time the next object with three different letters as value:

const XYZ = { I: 'X', II: 'Y', III: 'Z' };
const YZX = { I: 'Y', II: 'Z', III: 'X' };
const ZXY = { I: 'Z', II: 'X', III: 'Y' };
let nr = 1;

function getLetter() {
  let obj;
  if (nr == 1) {
    obj = XYZ;
    nr++;
    return obj;
  } else if (nr == 2) {
    obj = YZX;
    nr++;
    return obj;
  } else if (nr == 3) {
    obj = ZXY;
    nr = 1;
    return obj;
  }
}

server.js file

function intervalFunction() {
  insertCollection();
  consumeCollection();
  dropCollection();
}
if (isInserted  && isDropped) {
  setInterval(intervalFunction, 5000);
}

insertCollection.js Pseudo code to insert the "new" collection in MongoDB

let newCollectionName = `collection_${getLetter().III}`;
if (isNewCollectionNameInserted) isInserted = true;

consumeCollection.js Pseudo code to deliver the "actual" collection (after aggregation) in an API endpoint

let actualCollection = `collection_${getLetter().II}`;

dropCollection.js Pseudo code to drop the "old" collection from MongoDB

let oldCollection = `collection_${getLetter().I}`;
if (isOldCollectionDropped) isDropped = true;

2

Answers


  1. IMHO, you should not be storing ‘state’ in your nodejs code. Push that off to a service built for that.

    For your example, one approach (among many solutions) would be to use Redis to store a lock, and key/value of those configs..

    combo of using redis and redis-lock

    //insertCollection ....
    
    const client = require("redis").createClient(),
        lock = require("redis-lock")(client);
    
    async insertTheNewColleciton(collectionName) {
        const value = await client.get(collectionName);
        if(!value) {
            // insert new collection into mongo
    
            //add key to redis.
            await client.set(collectionName, 'i-exist');
        }
    }
    
    async doTheInsert(collectionName){
        await client.connect(); //will need to configure the connectivity
        
        console.log("Asking for lock");
        let done;
        try {
            done = await lock(collectionName); //lock on the collection name.   (you can also acquire a lock, with a time out)
            console.log("Lock acquired");
            await insertTheNewColleciton() // Some async task
    
            console.log("Releasing lock now");
    
        finally{
            if (done) { // even if an exception is thrown, or not.. release lock.
                await done()
            }
        }
    }
    

    Same Pattern for the Other Method… acquire the lock, do some work, close the lock

    This way.. your ‘server.js’ can actually put the methods in different api endpoints… and you call call each one separately or together. And now you can run this on multiple servers, and Redis will be to common ‘state’ store.

    Not the only answer, but one possible solution.

    Login or Signup to reply.
  2. Not sure I understand the problem but I will try to help:

    instead of 3 modules (insert, consume, drop) I would use 2:

    1. update collection
    2. consume collection

    getLetter.js utils file

        let index = 0;
        const letters = ['X', 'Y', 'Z'];
    
        function getLetter() {
          return letters[index];
        }
        
        function updateIndex() {
          index = (index + 1) % 3;
        }
        
        console.log(getLetter()); // X
        updateIndex();
        console.log(getLetter()); // Y
        
        

    Then you can do something like that:

    server.js file

    function intervalFunction() {
      updateCollection();
      consumeCollection();
    }
    
    setInterval(intervalFunction, 5000);

    updateCollection.js file

    updateCollection() {
      updateIndex();
    }

    consumeCollection.js file

    let actualCollection = `collection_${getLetter()}`;

    This way you won’t have to delete the collection every time.

    Hope it is what you looked for.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search