Sequential Number Generation Issue in Loop Using Queues

92 Views Asked by At

I've encountered a challenge in my current implementation. I'm utilizing queues to invoke a specific function (let's call it function a()) within a loop. The loop triggers the queue, leading to multiple calls of the same function a().

Inside function a(), I'm generating a number based on the totalCountOfSavedDocs + 1. For instance, if the savedOrders are 10, the next one should logically be 1. The generated number is then stored in the database (using mongodb) for the next doc saving.

However, due to the loop and the multiple queue calls, the number generation is not happening sequentially. Consequently, I'm facing an issue where the same number is being assigned to multiple documents.

I'd appreciate any insights or suggestions on how to ensure the sequential generation of numbers despite the loop and multiple queue calls.

Here is the code : This is how queue is called :

 for await (let order of orders) {
const msg: ServiceBusMessage = {
    body: JSON.stringify({
        type: "order-create-single",
        data: order,
        req: reqObj,
    })
};

await sender.sendMessages(msg); 
}

IN queue :

    public async process(orderObj: IOrderAddRequest, req: any) {
    try {
        await this.addOrderService.createOrder(req, orderObj);
    }
    catch (err) {
        throw err;
    }
}
1

There are 1 best solutions below

2
Sampath On

For messages that have been auto-forwarded, this property reflects the sequence number that had first been assigned to the message at its original point of submission. This property is read-only in Azure ServiceBus.

  • In MongoDB, we can use sequence number as a set and get. So you can update the sequential number in the message body and update in database with an increment. Start the sequential number from 1, get the sequential number from the database, and increment it before sending the queue/database. Refer to this doc for auto-incrementing IDs in MongoDB.

For creating a Service Bus client and sender for a queue. Refer to below:-

const serviceBusClient = new ServiceBusClient(connectionString);
const sender = serviceBusClient.createSender(queueName);

// Sample orders
const orders = [
    { orderId: 1, product: 'Product A' },
    { orderId: 2, product: 'Product B' },
    // Add more orders as needed
];
await sender.sendMessages(message);

getPreviousNumber Function:

async function getPreviousNumber(db, session) {
    const collection = db.collection('sequentialNumbers');
    const result = await collection.findOne({}, { session });
    return result ? result.number : 0;
}


storeNumberInDatabase

async function storeNumberInDatabase(db, session, number) {
    const collection = db.collection('sequentialNumbers');
    await collection.updateOne({}, { $set: { number } }, { upsert: true, session });
}


// Increment the shared counter to generate the next sequential number for Db
                const nextNumber = ++sharedCounter;

enter image description here

Azure: enter image description here