From a929d89fb3c0a58b56c2c832787d8d105f408ef6 Mon Sep 17 00:00:00 2001 From: jos3duardo Date: Sun, 17 Aug 2025 14:55:53 -0400 Subject: [PATCH] otimizado para funcionar sem limites de cpu e ram --- src/modules/database/database.module.ts | 4 +- .../processor/payment-default.processor.ts | 16 +---- .../processor/payment-fallback.processor.ts | 9 +-- .../payments/processor/payment.processor.ts | 16 +---- .../make-payment-to-processor.service.ts | 2 +- .../services/process-payment.service.ts | 72 ++++++++++++------- src/modules/queue/queue.module.ts | 1 + src/modules/queue/queue.service.ts | 8 +-- 8 files changed, 58 insertions(+), 70 deletions(-) diff --git a/src/modules/database/database.module.ts b/src/modules/database/database.module.ts index 6a34b5a..37b516a 100644 --- a/src/modules/database/database.module.ts +++ b/src/modules/database/database.module.ts @@ -16,10 +16,10 @@ import { Payment } from '../payments/entities/payment.entity'; database: configService.get('database.database'), entities: [Payment], extra: { - max: 5, + max: 10, // connectionTimeoutMillis: 3000, }, - synchronize: false, // Apenas para desenvolvimento + synchronize: false, }), inject: [ConfigService], }), diff --git a/src/modules/payments/processor/payment-default.processor.ts b/src/modules/payments/processor/payment-default.processor.ts index 5de9c23..2cae4d1 100644 --- a/src/modules/payments/processor/payment-default.processor.ts +++ b/src/modules/payments/processor/payment-default.processor.ts @@ -20,20 +20,6 @@ export class PaymentDefaultProcessor { async execute(payment: CreatePaymentDto): Promise { const url = this.configService.get('paymentProcessors.defaultUrl'); - const responseExists = await this.makePaymentToProcessorService.execute( - payment, - url, - ); - - if (!responseExists) return false; - await this.repository.query( - ` - INSERT INTO payments (correlation_id, amount, payment_processor) - VALUES ($1, $2, $3) - ON CONFLICT (correlation_id) DO NOTHING - `, - [payment.correlationId, payment.amount, ProcessorTypeEnum.DEFAULT], - ); - return true; + return await this.makePaymentToProcessorService.execute(payment, url); } } diff --git a/src/modules/payments/processor/payment-fallback.processor.ts b/src/modules/payments/processor/payment-fallback.processor.ts index eb7f0f9..8557203 100644 --- a/src/modules/payments/processor/payment-fallback.processor.ts +++ b/src/modules/payments/processor/payment-fallback.processor.ts @@ -15,13 +15,6 @@ export class PaymentFallbackProcessor { async execute(payment: CreatePaymentDto): Promise { const url = this.configService.get('paymentProcessors.fallbackUrl'); - const responseExists = await this.makePaymentToProcessorService.execute( - payment, - url, - ); - - if (!responseExists) return false; - - return true; + return await this.makePaymentToProcessorService.execute(payment, url); } } diff --git a/src/modules/payments/processor/payment.processor.ts b/src/modules/payments/processor/payment.processor.ts index d7268c8..2c31d41 100644 --- a/src/modules/payments/processor/payment.processor.ts +++ b/src/modules/payments/processor/payment.processor.ts @@ -8,7 +8,7 @@ import { Payment } from '../entities/payment.entity'; import { Repository } from 'typeorm'; import { CreatePaymentDto } from '../dto/create-payment.dto'; -@Processor(PAYMENT_QUEUE, { concurrency: 20 }) +@Processor(PAYMENT_QUEUE, { concurrency: 10 }) @Injectable() export class PaymentProcessor extends WorkerHost { private readonly logger = new Logger(PaymentProcessor.name); @@ -22,18 +22,6 @@ export class PaymentProcessor extends WorkerHost { } async process(job: Job) { - const payment = job.data; - const exists = await this.paymentRepository.findOne({ - where: { correlationId: payment.correlationId }, - }); - - if (!exists) { - try { - await this.processPaymentService.execute(payment); - } catch (error) { - this.logger.error(`Error processing payment: ${error.message}`); - throw error; - } - } + await this.processPaymentService.execute(job.data); } } diff --git a/src/modules/payments/services/make-payment-to-processor.service.ts b/src/modules/payments/services/make-payment-to-processor.service.ts index 3d880a0..fb2c470 100644 --- a/src/modules/payments/services/make-payment-to-processor.service.ts +++ b/src/modules/payments/services/make-payment-to-processor.service.ts @@ -23,7 +23,7 @@ export class MakePaymentToProcessorService { const response = await firstValueFrom( this.httpService.post(`${url}/payments`, paymentData, { - timeout: 2500, + timeout: 3000, }), ); return response.status === 200; diff --git a/src/modules/payments/services/process-payment.service.ts b/src/modules/payments/services/process-payment.service.ts index 353a3f3..f1738df 100644 --- a/src/modules/payments/services/process-payment.service.ts +++ b/src/modules/payments/services/process-payment.service.ts @@ -13,43 +13,63 @@ export class ProcessPaymentService { constructor( @InjectRepository(Payment) private readonly repository: Repository, - private paymentDefaultProcessor: PaymentDefaultProcessor, private paymentFallbackProcessor: PaymentFallbackProcessor, ) {} async execute(job: CreatePaymentDto): Promise { - let result = false; + const existingPayment = await this.repository.findOne({ + where: { correlationId: job.correlationId }, + }); + + if (existingPayment) return; + + let defaultSuccess = false; try { - result = await this.paymentDefaultProcessor.execute(job); + defaultSuccess = await this.paymentDefaultProcessor.execute(job); + + if (defaultSuccess) { + await this.savePayment(job, ProcessorTypeEnum.DEFAULT); + return; + } } catch (error) { if (error.response?.status === 422) { - await this.repository.query( - ` - INSERT INTO payments (correlation_id, amount, payment_processor) - VALUES ($1, $2, $3) - ON CONFLICT (correlation_id) DO NOTHING - `, - [job.correlationId, job.amount, ProcessorTypeEnum.DEFAULT], - ); - this.logger.warn( - `Pagamento já realizado para correlationId: ${job.correlationId}`, - ); - return; // Não lança exceção, job é considerado processado + await this.savePayment(job, ProcessorTypeEnum.DEFAULT); + return; } this.logger.warn(`Default processor failed: ${error.message}`); } - if (!result) { - await this.paymentFallbackProcessor.execute(job); - await this.repository.query( - ` - INSERT INTO payments (correlation_id, amount, payment_processor) - VALUES ($1, $2, $3) - ON CONFLICT (correlation_id) DO NOTHING - `, - [job.correlationId, job.amount, ProcessorTypeEnum.FALLBACK], - ); + + let fallbackSuccess = false; + try { + fallbackSuccess = await this.paymentFallbackProcessor.execute(job); + + if (fallbackSuccess) { + await this.savePayment(job, ProcessorTypeEnum.FALLBACK); + return; + } + } catch (error) { + if (error.response?.status === 422) { + await this.savePayment(job, ProcessorTypeEnum.FALLBACK); + + return; + } + + throw new Error(`Payment processing failed for ${job.correlationId}`); } - throw new Error('Payment processing failed'); + } + + private async savePayment( + job: CreatePaymentDto, + processor: ProcessorTypeEnum, + ): Promise { + await this.repository.query( + ` + INSERT INTO payments (correlation_id, amount, payment_processor) + VALUES ($1, $2, $3) + ON CONFLICT (correlation_id) DO NOTHING + `, + [job.correlationId, job.amount, processor], + ); } } diff --git a/src/modules/queue/queue.module.ts b/src/modules/queue/queue.module.ts index 530d7cb..b7dee7f 100644 --- a/src/modules/queue/queue.module.ts +++ b/src/modules/queue/queue.module.ts @@ -9,6 +9,7 @@ import { PAYMENT_QUEUE } from './constants/queue.constants'; connection: { host: 'redis', port: 6379, + enableReadyCheck: false, }, }), BullModule.registerQueue({ diff --git a/src/modules/queue/queue.service.ts b/src/modules/queue/queue.service.ts index 210b4b6..06f678e 100644 --- a/src/modules/queue/queue.service.ts +++ b/src/modules/queue/queue.service.ts @@ -11,13 +11,13 @@ export class QueueService { async addPaymentJob(data: CreatePaymentDto): Promise { await this.paymentQueue.add(PAYMENT_QUEUE, data, { jobId: data.correlationId, - attempts: 60, + attempts: 100, backoff: { type: 'exponential', - delay: 3000, + delay: 100, }, - removeOnComplete: 100, - removeOnFail: 50, + removeOnComplete: true, + removeOnFail: 101, }); } }