Closed jayakusumah closed 4 years ago
@jayakusumah Thanks for reporting this
I'll try to look into this issue in the next few days. It'd be great if, in the meantime, you could provide some code reproducing this error, or even submit a PR with failing tests.
I got the same problem: controllers in others module cannot inject queue defined in another module.
I tried exports processors, import queue defined module but no luck.
https://github.com/smonv/bull-queue-test here is code for quick setup demo the problem
I found a workaround to solve this problem. Instead of directed inject queue inside controller, indirect inject queue by a service.
Create a task service inside QueueModule
so naturally that service can inject queue. Export task service and let other controllers import it.
Same issue, in my case I need to use registerAsync
so that I can load my ConfigService to get redis credentials from.
I think I've found the issue, when you use registerAsync
it doesn't respect the name from the options and registering the ff instead of the name used in registerAsync
@smonv The queue can only be injected in the scope where BullModule
has been registered. That's why you can't directly inject it in another module without wrapping it in a service that you export. This is the expected behavior.
Also I don't think this has anything to do with what @jayakusumah and @captainjapeng are reporting.
@captainjapeng might be right here. There seems to be a confusion between the name of the options and the name of the queue. I'll see what can be done to prevent this kind of error.
EDIT: Well, @captainjapeng is actually right.
BullModule.register
: the BullModuleOptions.name
is used as the queue name and as the queue injection token also.BullModule.registerAsync
: the BullModuleAsyncOptions.name
is used as the injection token and the BullModuleOptions.name
is used as the queue name.I'm experiencing this same problem. Is there a work around at this moment?
Yes, you'll need to create a module to reexport the BullModule
Here's an example:
import { BullModule, BullModuleOptions } from 'nest-bull'
import { Module } from '@nestjs/common'
import { ConfigModule } from 'src/config/config.module'
import { ConfigService } from 'src/config/config.service'
function redisOptions(configService: ConfigService) {
return {
host: configService.getString('REDIS_HOST'),
port: configService.getInt('REDIS_PORT'),
}
}
const BullQueueModule = BullModule.registerAsync([
{
name: 'email',
imports: [ConfigModule],
useFactory: (configService: ConfigService): BullModuleOptions => {
return {
name: 'email',
options: {
redis: redisOptions(configService),
},
}
},
inject: [ConfigService],
},
{
name: 'cron',
imports: [ConfigModule],
useFactory: (configService: ConfigService): BullModuleOptions => {
return {
name: 'cron',
options: {
redis: redisOptions(configService),
},
}
},
inject: [ConfigService],
},
])
@Module({
imports: [BullQueueModule],
exports: [BullQueueModule],
})
export class QueueModule { }
had the same issue. really glad i found this thread here, otherwise there is no documentation yet. It would be really great if it could be added to the readme. Thanks!
Yes, you'll need to create a module to reexport the BullModule
Here's an example:
import { BullModule, BullModuleOptions } from 'nest-bull' import { Module } from '@nestjs/common' import { ConfigModule } from 'src/config/config.module' import { ConfigService } from 'src/config/config.service' function redisOptions(configService: ConfigService) { return { host: configService.getString('REDIS_HOST'), port: configService.getInt('REDIS_PORT'), } } const BullQueueModule = BullModule.registerAsync([ { name: 'email', imports: [ConfigModule], useFactory: (configService: ConfigService): BullModuleOptions => { return { name: 'email', options: { redis: redisOptions(configService), }, } }, inject: [ConfigService], }, { name: 'cron', imports: [ConfigModule], useFactory: (configService: ConfigService): BullModuleOptions => { return { name: 'cron', options: { redis: redisOptions(configService), }, } }, inject: [ConfigService], }, ]) @Module({ imports: [BullQueueModule], exports: [BullQueueModule], }) export class QueueModule { }
Hi @captainjapeng ,
Could you please share full example with usage, I tried re-export but still got same error.
@maxymshg you'll need to import the QueueModule
to the module you want to use it and then also setup your Processor on the Providers
email.module.ts
@Module({
imports: [
forwardRef(() => QueueModule),
],
providers: [EmailService, CronProcessor],
exports: [EmailService],
})
export class EmailModule {}
cron.processor.ts
@Injectable()
@Processor({ name: 'cron' })
export class CronProcessor {
private readonly logger = new Logger('EmailCron')
constructor(
@InjectQueue('email')
private queueService: Queue<EmailJob>,
@InjectQueue('cron')
private cron: Queue,
) {
this.logger.log('Intializing Cron Processor')
cron.add(null, {
repeat: { cron: '0 0 1-2 * * *' },
jobId: 'resume-email',
})
}
@Process()
async process(job: Job) {
this.logger.log('Resuming Email Service')
await this.queueService.resume()
}
}
Here's an example of a cron job that resume the email queue every 1-2 AM UTC if ever the quota has been reached.
Got it, thanks for sharing this.
Hi, I tried it, but i have the same problem. When you give a name (@Processor({ name: 'foo' }), this.moduleRef.get cannot find the object. But it work very well with @Processor({ name: '' }) and InjectQueue('').
Let's track this here https://github.com/nestjs/bull/issues/171
I get an error Nest can't resolve dependencies of the controller (service, ?).... Please make sure that the argument at index [1] is available when using BullModule.registerAsync, but it works fine when using BullModule.register(). I use a shared module, and import it in another module.
nest-bull version 0.8.4