Home > Software engineering >  How to share a single promise based RabbitMQ connection across files or controllers in Node js inste
How to share a single promise based RabbitMQ connection across files or controllers in Node js inste

Time:10-16

amqplib library lets you create a rabbitmq connection and that object will be a segue to doing other things such as creating a channel and etc.

suppose that I'm going for a Producer/Consumer pattern, where each time a user hits a specific route, a job is produced and sent to the rabbitmq server where it's processed by certain consumers(workers).

app.post("/routethatdelegatesheavywork", async (req,res) => { 
  const amqpServerLink =
        "link-to-cloudmq";
      const connection = await amqp.connect(amqpServerLink);
      const channel = await connection.createChannel();
      //do other stuff with channel
})

while this "works", but i don't want to re-create that connection every time the controller is invoked since it makes the producer very slow and it's really not how it's supposed to be done.

here is where my problem comes:

how do i initialize one connection and re-use it every time i need it?

i have tried to create a connection outside controllers and use it when necessary but it's not possible since the connection is promise-based and await doesn't work on entry point and it has to be inside an async function to work.

although it is possible to run await without async using ESM (es modules) i don't want to do so since i have written all of the application using CommonJS (require("package")), changing that would require me to go through a lot of files and change every import/export according to ESM.

So, is there any other way to create one connection(that is promise based) and re-use it without having to migrate to ESM syntax?

CodePudding user response:

Yes, remember that require in nodejs are singletons. Make a new amqpServerInterface module, and do

const amqpServerLink = "link-to-cloudmq"
const connection = amqp.connect(amqpServerLink)

function connect() {
      return connection
}

module.exports = {
     connect
}

Then in your controllers

const amqpServerInterface = require('amqpServerInterface')

app.post("/routethatdelegatesheavywork", async (req,res) => { 
 
      const connection = await amqpServerInterface.connect();
      const channel = await connection.createChannel();
      //do other stuff with channel
})

This will always return the same connection promise and will resolve to the save connection.

  • Related