How to Handle Multiple user request at the same time in node js

1.9k Views Asked by At

I have created a route '/api/checkUsername'. Which action is to check if there is any user exists with the same username. If not Save the new UserName in users collection and update the users count in another collection.

For the route, I have a function as

async function(username) {
   IsUserNameExists = await db.findOne({ 'username': username });

   if(IsUserNameExists) {
      res.send({ message: 'username already exists');  
  }else{
      await user.save() //to save user in DB
      await updateUserCount() //update user count in collection 2 
      res.send({ message: 'user saved successfully' });
  } 

}

This works fine with all use cases. But a case like if 2 users ['user1', 'user2'] user check for the same username eg: Tony_Stark at the same second or with few milli-second difference.

eg user1 and user2 hits /api/checkUsername at the same time or with millisecond difference. user 1 finds that username Tony_Stark is available and saving his username, but in between saving the user name the user2 also looks for the username Tony_Stark which has not been saved by user1, So it makes that username available for user2 also. Which creates a duplicate entry in my collection. How do I avoid this?

1

There are 1 best solutions below

0
Dhruvil Shah On

You can solve this problem using the mutex as this is a problem of mutual execution using the library async-mutex

npm install async-mutex

or

yarn add async-mutex

So your solution will look like

import { Mutex, MutexInterface } from 'async-mutex';

const mutex = new Mutex();

createUser = async (userName) => {
    mutex
    .acquire()
    .then(async (release) => {
                try {
                    const IsUserNameExists = await db.findOne({ 'username': username });
                    if (!IsUserNameExist) {
                        // ... Statement to create user
                    }
                } catch (error) {
                } finally {
                    release();
                }
            },
}