golevelup / nestjs

A collection of badass modules and utilities to help you level up your NestJS applications 🚀

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support pre-defined consumer tag

huantaoliu opened this issue · comments

Is there a way to add a user defined consumerTag into RabbitMQConfig ? It is possiblily through underlying channel.consume function of amqplib https://amqp-node.github.io/amqplib/channel_api.html#channel_consume.

My usecase is that I am doing a multi-tanant application, where I dynamically register multiple rmq instances. I subscribe all the instances messages through one RabbitSubscribe ( i can't create one RabbitSubscribe for each instance, with it's own queue name, as it's coming as dynamic request to create the connection for new tenant, so i don't know their name before hand.)

So my solution is to have one predefined RabbitSubscribe,

  @RabbitSubscribe({
    queue: 'the-only-queue-name-that-every-tenant-share',
    exchange: 'exchange-name-all-tenants-share',
    routingKey: 'routing-key-all-tentants-share',
    queueOptions: {
      durable: true,
      arguments: { 'x-message-ttl': 60000, 'x-max-length': 1000 }
    },
    createQueueIfNotExists: false, //remove this when bug fixed
  })
processMessage()...

At first glance, this will work, processMessage() will get all messages coming from all tentant's rmq.
To seperate which message is for which tenant, I rely on consumer tag. When I dynamically create new rabbitmq connection for a new tenant, I take a note of cunsumerTag, which will map to the tenant, so my processMessage() will process differently according to different tenants.

The above theory all works fine, except when I come accross application downtime. When I re-start the application, I get the messages (generated during app down time) before I get consumer tag.

 return await connection.createSubscriber(handler, mergedConfig, discoveredMethod.methodName);

before the await finish, my RabbitSubscribe already starts to get messges.

My problem can also be soved, if I can start to receive message only after createSubscriber is really finished.

 return await connection.createSubscriber(handler, mergedConfig, discoveredMethod.methodName);

@huantaoliu Thank you for providing this information. As i usually say i haven't been using RMQ package for awhile but I'm always open to seeing great feedback and contributions.
If you feel like pushing this feature, I'll happily review