Я пытаюсь интегрировать bullmq
в проект NestJs. Но столкнулся со следующей ошибкой:
Error: Nest can't resolve dependencies of the CustomerSubscriptionPaymentsService (CustomerSubscriptionPaymentsRepo, ?). Please make sure that the argument "BullQueue_invoice" at index [1] is available in the CustomerSubscriptionPaymentsModule context.
Potential solutions:
- Is CustomerSubscriptionPaymentsModule a valid NestJS module?
- If "BullQueue_invoice" is a provider, is it part of the current CustomerSubscriptionPaymentsModule?
- If "BullQueue_invoice" is exported from a separate @Module, is that module imported within CustomerSubscriptionPaymentsModule?
@Module({
imports: [ /* the Module containing "BullQueue_invoice" */ ]
})
Вот каталог проекта:
modules
app
app.module.ts
app.controller.ts
customerSubscriptionPayments
customerSubscriptionPayments.module.ts
customerSubscriptionPayments.service.ts
customerSubscriptionPayments.controller.ts
invoice
invouce.module.ts
invoice.controller.ts
invoice.service.ts
invoice.processor.ts
app.module.ts
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { AppController } from './app.controller';
import { CustomerSubscriptionPaymentsModule } from '../customerSubscriptionPayments/customerSubscriptionPayments.module';
import { CustomerSubscriptionPaymentsService } from '../customerSubscriptionPayments/customerSubscriptionPayments.service';
@Module({
imports: [
BullModule.forRoot({
connection: {
host: 'localhost',
port: 6379,
},
}),
CustomerSubscriptionPaymentsModule,
],
providers: [CustomerSubscriptionPaymentsService],
controllers: [AppController],
})
export class AppModule {}
счет-фактура.module.ts
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { InvoiceController } from './invoice.controller';
import { InvoiceService } from './invoice.service';
import { InvoiceRepo } from './invoice.repo';
import { RedisQueues } from 'src/constants';
import { InvoiceProcessor } from './invoice.processor';
@Module({
imports: [
BullModule.registerQueue({
name: 'invoice',
}),
],
controllers: [InvoiceController],
providers: [InvoiceService, InvoiceRepo],
exports: [InvoiceService, InvoiceRepo],
})
export class InvoiceModule {}
счет-фактура.processor.ts
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';
import { InvoiceQueueTasks } from './constants';
@Processor('invoice')
export class InvoiceProcessor extends WorkerHost {
async generateInvoice(job: Job) {
const { data } = job;
if (data.customerSubscriptionId) {
console.error('customerSubscriptionId not found');
return {};
}
//TODO: Implement invoice generation logic
}
async process(job: Job) {
const { data, name } = job;
if (name === InvoiceQueueTasks.GENERATE) {
return this.generateInvoice(job);
}
return {};
}
}
customerSubscriptionPayments.module.ts
import { Module } from '@nestjs/common';
import { CustomerSubscriptionPaymentsController } from './customerSubscriptionPayments.controller';
import { CustomerSubscriptionPaymentsRepo } from './customerSubscriptionPayments.repo';
import { CustomerSubscriptionPaymentsService } from './customerSubscriptionPayments.service';
@Module({
controllers: [CustomerSubscriptionPaymentsController],
providers: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
exports: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
})
export class CustomerSubscriptionPaymentsModule {}
customerSubscriptionPayments.service.ts
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
@Injectable()
export class CustomerSubscriptionPaymentsService {
constructor(@InjectQueue('invoice') private invoiceQueue: Queue) {}
async generateInvoice() {
const job = await this.invoiceQueue.add('generate', {
customerSubscriptionId: 1,
});
if (!job) {
throw new HttpException(
'Failed to generate invoice',
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
return {
success: true,
};
}
}
🤔 А знаете ли вы, что...
Node.js имеет интегрированный менеджер пакетов npm для управления зависимостями.
Проблема в том, что вы не импортируете свою Bull Queue в свой модуль customerSubscriptionPayments, поэтому, когда вы попытаетесь внедрить ее в службу customerSubscriptionPayments, она не сможет разрешить зависимость.
@Module({
imports: [
BullModule.registerQueue({
name: 'invoice',
}),
]
controllers: [CustomerSubscriptionPaymentsController],
providers: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
exports: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
})
Другой способ сделать что-то
Поскольку в документации NestJS нет документации, показывающей, как экспортировать зарегистрированную Bull Queue, вы можете создать Module
, который экспортирует Service
, который обрабатывает очередь независимо, после этого вы можете импортировать этот модуль в другие сервисы, чтобы вы могли добавлять, удалять или выполнять любые действия. действие, связанное с очередью, в любой нужной вам службе. Вы можете сделать это в своем Invoice Module
, поскольку именно там вы в первую очередь регистрировали очередь.
Пример:
Модуль счетов
@Module({
imports: [
BullModule.registerQueue({
name: 'invoice',
}),
],
controllers: [InvoiceController],
providers: [InvoiceService, InvoiceRepo, InvoiceQueueHandler],
exports: [InvoiceService, InvoiceRepo, InvoiceQueueHandler],
})
export class InvoiceModule {}
Обработчик очереди счетов
export class InvoiceQueueHandler(){
constructor(InjectQueue('invoice') private invoiceQueue: Queue){}
addJob(){
// perform some action
}
// rest of your functions to handle the queue
}
КлиентПодпискаПлатежный модуль
@Module({
import: [InvoiceModule]
controllers: [CustomerSubscriptionPaymentsController],
providers: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
exports: [
CustomerSubscriptionPaymentsService,
CustomerSubscriptionPaymentsRepo,
],
})
export class CustomerSubscriptionPaymentsModule {}
КлиентПодпискаПлатежный модуль
@Injectable()
export class CustomerSubscriptionPaymentsService {
constructor(private invoiceQueueHandler: InvoiceQueueHandler) {}
someFunction(){
this.invoiceQueueHandler.addJob()
}
}