golevelup / nestjs

A collection of badass modules and utilities to help you level up your NestJS applications 🚀
MIT License
2.23k stars 259 forks source link

[RabbitMQ] Prevent Amqp connection when running the NestJS application in standalone #572

Open dennis0126 opened 1 year ago

dennis0126 commented 1 year ago

Sometimes I would like to run the NestJS application in standalone without connecting to a real RabbitMQ instance. For example, I have processes that seed the database or generate the Swagger doc, which will start the NestJS application but do not require RabbitMQ communication.

However, I found no ways to prevent connecting to RabbitMQ instance. connection.init() is called when RabbitMQModule is first created. https://github.com/golevelup/nestjs/blob/master/packages/rabbitmq/src/rabbitmq.module.ts#L84

I got the following error when trying to initialize the NestJS application.

[Nest] 23152  - 03/20/2023, 4:14:17 PM   ERROR [AmqpConnection] Disconnected from RabbitMQ broker (default)

[Nest] 23152  - 03/20/2023, 4:14:22 PM   ERROR [ExceptionHandler] Failed to connect to a RabbitMQ broker within a timeout of 5000ms

Setting registerHandlers: false does not help in this case. Is there any way that I can initialize the NestJS application without throwing error in AmqpConnection?

nolawnchairs commented 1 year ago

Getting the same issue when running a debugger. The connection times out and crashes

kakui-lau commented 1 year ago

Have you solved the same problem?

xBajci commented 1 year ago

I have the same use case. I'd like to start the app without the rabbit trying to connect. We are using ConfigMudule to provide rabbitmq options and if enabled is false the rabbit should not try to connect.

@Module({
  imports: [
    RabbitMQModule.forRootAsync(RabbitMQModule, {
      inject: [ConfigService],
      useFactory: async (config: ConfigService<AppConfig, true>) => {
        const rabbitMqConfig = config.get<AppConfig['rabbitmq']>('rabbitmq');

        return {
          exchanges: [
            {
              name: rabbitMqConfig.exchange,
              type: rabbitMqConfig.topic,
            },
          ],
          uri: rabbitMqConfig.uri,
          prefetchCount: rabbitMqConfig.prefetchCount,
        };
      },
    }),
  ],
  exports: [RabbitMQModule],
})
export class AmqpModule {}

What would be the best way to implement it?

One solution could be to dynamically register a custom amqp module that based on the config registers either the original rabbitMq module or a mocked module with a mocked provider. But that sounds like too much work for this simple thing.

huantaoliu commented 8 months ago

I have the same usecase, where I want to register rabbitmq dynamically and programatically.

Maybe we can add a flag and pass to AmqpConnectionFactory(), so it won't call init() if the flag is false. then latter onApplicationBootstrap() won't need to process any connections. That might work. I can try to put up a MR if the author thinks it's a good approach.

underfisk commented 7 months ago

@huantaoliu I generally like that idea, we could add a flag to skip initialization, feel free to create a PR with a proposal and I'll review it

huantaoliu commented 7 months ago

ok will work on that.

LucasHang commented 4 months ago

Perhaps this optinal config can be useful? In theory, it allows to avoid connection during bootstrap and adding the connection in another moment.