Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: channel is not available #423

Closed
singhajit1616 opened this issue Apr 16, 2022 · 10 comments
Closed

Error: channel is not available #423

singhajit1616 opened this issue Apr 16, 2022 · 10 comments
Labels

Comments

@singhajit1616
Copy link

singhajit1616 commented Apr 16, 2022

I'm creating an API which will accept the message and then will publish it to the queue.

So i have initialized my app.module.ts

@Module({
  imports: [
     RabbitMQModule.forRootAsync(RabbitMQModule, {
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        uri: configService.get('RABBIT_MQ_URI')
      })
    }),
  ],
  controllers: [AppController],
  providers: [
    AppService
  ],
})
export class AppModule {}

And in the service imported the library AMQPService like this constructor(private readonly amqpConnection: AmqpConnection){}

So when, using the methods exposed like this this.amqpConnection.channel.assertExchange(exchange.name, exchange.type, exchange.options); and it throws Error: channel is not available.

When logged amqpConnection, recieved this object

AmqpConnection {
  messageSubject: Subject {
    closed: false,
    currentObservers: null,
    observers: [],
    isStopped: false,
    hasError: false,
    thrownError: null
  },
  logger: Logger { context: 'AmqpConnection', options: {} },
  initialized: Subject {
    closed: false,
    currentObservers: null,
    observers: [],
    isStopped: false,
    hasError: false,
    thrownError: null
  },
  _managedChannels: {},
  _channels: {},
  config: {
    prefetchCount: 10,
    defaultExchangeType: 'topic',
    defaultRpcErrorBehavior: 'REQUEUE',
    defaultSubscribeErrorBehavior: 'REQUEUE',
    exchanges: [],
    defaultRpcTimeout: 10000,
    connectionInitOptions: { wait: true, timeout: 5000, reject: true },
    connectionManagerOptions: {},
    registerHandlers: true,
    enableDirectReplyTo: true,
    channels: {},
    enableControllerDiscovery: false
  }
}

Expectations:

  • Should be able to assert an exchange.
@WonderPanda
Copy link
Collaborator

Can you please share an example repo that demonstrates the issue so that it can be properly investigated?

@singhajit1616
Copy link
Author

@WonderPanda
Copy link
Collaborator

Where is the value for RABBIT_MQ_URI coming from in your setup?

@singhajit1616
Copy link
Author

singhajit1616 commented Apr 19, 2022

@WonderPanda getting these values from .env file. And have updated the repo. And I have noticed that AmqpConnection is creating a new instance as while creating the connection i have configured it something like this

RabbitMQModule.forRootAsync(RabbitMQModule, {
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        uri: configService.get('RABBIT_MQ_URI'),
        prefetchCount: 100,
        connectionInitOptions: { wait: false }
      })
    })

And the log is also showing the same config under the package

{
  prefetchCount: 100,
  defaultExchangeType: 'topic',
  defaultRpcErrorBehavior: 'REQUEUE',      
  defaultSubscribeErrorBehavior: 'REQUEUE',
  exchanges: [],
  defaultRpcTimeout: 10000,
  connectionInitOptions: { wait: false },  
  connectionManagerOptions: {},
  registerHandlers: true,
  enableDirectReplyTo: true,
  channels: {},
  enableControllerDiscovery: false,
  uri: 'amqp://guest:guest@localhost:5672'
}

But while accessing the connection through AmqpConnection the config object is different

{
  prefetchCount: 10,
  defaultExchangeType: 'topic',
  defaultRpcErrorBehavior: 'REQUEUE',
  defaultSubscribeErrorBehavior: 'REQUEUE',
  exchanges: [],
  defaultRpcTimeout: 10000,
  connectionInitOptions: { wait: true, timeout: 5000, reject: true },
  connectionManagerOptions: {},
  registerHandlers: true,
  enableDirectReplyTo: true,
  channels: {},
  enableControllerDiscovery: false
}

@nitoba
Copy link

nitoba commented Apr 24, 2022

Hello, I have similar trouble.

This is my module

@Module({
  imports: [
    RabbitMQModule.forRootAsync(RabbitMQModule, {
      useFactory: createRabbitMqConfig,
      inject: [ConfigService],
    }),
  ],
  providers: [RabbitMqService],
  exports: [RabbitMqService],
})
export class RabbitModule {}

This is an config file that export an function with configuration file

import { RabbitMQConfig } from '@golevelup/nestjs-rabbitmq';
import { ConfigService } from '@nestjs/config';

export const createRabbitMqConfig = (configService: ConfigService) => {
  const config: RabbitMQConfig = {
    exchanges: [
      {
        name: 'amq.direct',
        type: 'direct',
      },
    ],
    channels: {
      'channel-1': {
        default: true,
      },
    },
    uri: configService.get<string>('RABBITMQ_CONNECTION_URL'),
    enableControllerDiscovery: true,
    connectionInitOptions: { wait: true },
  };
  return config;
};

This is my service file

import { AmqpConnection, RabbitSubscribe } from '@golevelup/nestjs-rabbitmq';
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';

@Injectable()
export class RabbitMqService implements OnModuleInit, OnModuleDestroy {
  constructor(private readonly amqpConnection: AmqpConnection) {}

  @RabbitSubscribe({
    exchange: 'amq.direct',
    routingKey: 'messages',
    queue: 'messages',
    queueOptions: {
      channel: 'channel-1',
    },
  })
  message(message) {
    console.log(message);
  }

  async publishMessage(message) {
    await this.amqpConnection.publish('amq.direct', 'messages', message);
  }

  onModuleDestroy() {
    console.log('RabbitMqService destroyed');
  }
  async onModuleInit() {
    console.log('RabbitMqService initialized');
  }
}

The basic problem is that the "amqpConnection" is not injected on service and due this is undefined

@nitoba
Copy link

nitoba commented Apr 24, 2022

I think this is bug of the version 2.3.0
In version "@golevelup/nestjs-rabbitmq": "2.2.0" all works fine

@fmalk
Copy link

fmalk commented May 26, 2022

I can attest downgrading to 2.2.0 works.
We were refactoring our code from vanilla NestJS messaging to this library. We have a Web runtime that processes HTTP request and sends to fanout queues, and Worker runtime processing jobs.
We got to a point where Web was downgraded and we forgot to downgrade Workers', and the Messaging Module is even a shared git between those two apps. Only the Worker 2.3.x version was receiving an undefined AmqpConnection. After also downgrading it, worker's running fine.

@andrewda
Copy link
Contributor

@singhajit1616 @nitoba @fmalk Try specifying default: true in your connection options. It looks like this may have been an unintentional breaking change in #411. If that fixes the issue, I can update the documentation and try to make the defaults make more sense!

@fmalk
Copy link

fmalk commented Jul 29, 2022

Since we're still using 2.2 for our backend, best if we tried to update it to current version and see if problem persist. However that's not a priority.
When that happens, I'll report back here.

@nerdyman
Copy link

Also getting this in the latest (3.4.0) and 3.3.0. 3.2.0 works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants