Reputation: 197
I have the following code:
transaction.processor.ts
import { Process, Processor } from '@nestjs/bull';
import { TransactionService } from '@src/modules/transaction/transaction.service';
import { Job } from 'bull';
export const transactionQueue = 'TransactionQueue';
export const transactionJob = 'TransactionJob';
@Processor(transactionQueue)
export class TransactionProcessor {
constructor(private readonly _transactionService: TransactionService) {}
@Process(transactionJob)
async handleFinalizeTransaction(job: Job) {
const { transactionId } = job.data;
try {
await this._transactionService.finalizeTransaction(transactionId);
} catch (error) {
console.error('Error finalizing transaction:', error);
throw error;
}
}
}
transaction.service.ts
import { InjectQueue } from '@nestjs/bull';
import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { BaseService } from '@src/core/bases/base.service';
import { ErrorMessages } from '@src/core/enums/error-messages.enum';
import { Roles } from '@src/core/enums/roles.enum';
import { TransactionStatus } from '@src/core/enums/transaction-status.enum';
import { InputTransactionPaginationDto } from '@src/modules/transaction/dtos/input.transaction-pagination.dto';
import { TransactionEntity } from '@src/modules/transaction/entities/transaction.entity';
import { transactionJob, transactionQueue } from '@src/modules/transaction/queues/transaction.processor';
import { UserEntity } from '@src/modules/user/entities/user.entity';
import { pagination } from '@src/utils/utils';
import { Queue } from 'bull';
import { Repository } from 'typeorm';
@Injectable()
export class TransactionService extends BaseService<TransactionEntity> {
constructor(
@InjectRepository(TransactionEntity) private _transactionRepository: Repository<TransactionEntity>,
@InjectQueue(transactionQueue)
private readonly _transactionQueue: Queue,
) {
super(_transactionRepository);
}
async createTransaction(user: UserEntity, teacher: UserEntity, amount: number) {
if (user.tokens < amount) {
throw new BadRequestException(ErrorMessages.INSUFFICIENT_TOKENS);
}
user.tokens -= amount;
await this._transactionRepository.save(user);
const transaction = this._transactionRepository.create({
user,
teacher,
amount,
status: TransactionStatus.ACTIVE,
});
await this._transactionQueue.add(
transactionJob,
{ transactionId: transaction.id },
{ delay: 14 * 24 * 60 * 60 * 1000 },
);
await this._transactionRepository.save(transaction);
return transaction;
}
}
Unfortunately, in console I've got:
Nest can't resolve dependencies of the TransactionService (TransactionEntityRepository, ?). Please make sure that the argument BullQueue_default at index [1] is available in the TransactionModule context.
When I remove transactionService
from processor
then it works but I need to use this service there. Is that some kind of circular dependency? In my transacion.module.ts
I have:
import { BullModule } from '@nestjs/bull';
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TransactionEntity } from '@src/modules/transaction/entities/transaction.entity';
import { TransactionProcessor, transactionQueue } from '@src/modules/transaction/queues/transaction.processor';
import { TransactionController } from '@src/modules/transaction/transaction.controller';
import { TransactionService } from '@src/modules/transaction/transaction.service';
@Module({
providers: [TransactionService, TransactionProcessor],
imports: [
TypeOrmModule.forFeature([TransactionEntity]),
PassportModule.register({ defaultStrategy: 'jwt' }),
BullModule.registerQueue({ name: transactionQueue }),
],
controllers: [TransactionController],
exports: [TransactionService, BullModule],
})
export class TransactionModule {}
Upvotes: 0
Views: 164
Reputation: 196
Yes it's circular dependencies. Because the service inject the queue and your queue use the service
In your case you should change the pattern and maybe work with the event system of nest js.
Imagine triggering a CreatedTransaction event that queue a new Transaction job. It's preventing the circular dependancies because
For my personal use case i just created a new service that just enqueue because methods were call from the controller
Upvotes: 0
Reputation: 97
If you are importing the TransactionService into another module I think you might need to register the queue again in the new module.
import { Module } from '@nestjs/common';
import { NewService } from './new.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NewEntity } from './entities/new.entity';
import { BullModule } from '@nestjs/bull';
import { transactionQueue } from '@src/modules/transaction/queues/transaction.processor';
import { TransactionModule } from '@src/modules/transaction/transaction.module';
@Module({
imports: [
TransactionModule,
TypeOrmModule.forFeature([NewEntity]),
BullModule.registerQueue({
name: transactionQueue,
}),
],
providers: [NewService],
exports: [NewService],
})
export class NewModule {}
Upvotes: 0