chore: update the processor of the notification

This commit is contained in:
Mahyargdz
2025-05-11 14:57:04 +03:30
parent 78d143fa85
commit e7c3d8105f
2 changed files with 120 additions and 89 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ export function databaseConfigs(): TypeOrmModuleAsyncOptions {
username: configService.getOrThrow<string>("DB_USER"), username: configService.getOrThrow<string>("DB_USER"),
password: configService.getOrThrow<string>("DB_PASS"), password: configService.getOrThrow<string>("DB_PASS"),
autoLoadEntities: true, autoLoadEntities: true,
synchronize: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true, synchronize: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : false,
logging: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true, logging: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true,
migrationsTableName: "typeorm_migrations", migrationsTableName: "typeorm_migrations",
migrationsRun: false, migrationsRun: false,
@@ -41,7 +41,12 @@ type NotificationJobData = {
| INewTicketNotificationData; | INewTicketNotificationData;
}; };
@Processor(NOTIFICATION.QUEUE_NAME, { concurrency: 5 }) @Processor(NOTIFICATION.QUEUE_NAME, {
concurrency: 5,
lockDuration: 30000, // 30 seconds lock duration
stalledInterval: 30000, // Check for stalled jobs every 30 seconds
maxStalledCount: 2, // Allow 2 stalls before failing
})
export class NotificationProcessor extends WorkerProcessor { export class NotificationProcessor extends WorkerProcessor {
protected readonly logger = new Logger(NotificationProcessor.name); protected readonly logger = new Logger(NotificationProcessor.name);
@@ -62,103 +67,129 @@ export class NotificationProcessor extends WorkerProcessor {
await queryRunner.connect(); await queryRunner.connect();
await queryRunner.startTransaction(); await queryRunner.startTransaction();
const heartbeat = setInterval(() => {
job.updateProgress(50);
}, 10000); // Update progress every 10 seconds
const { type, recipientId, data } = job.data; const { type, recipientId, data } = job.data;
switch (type) { try {
// Admin Notifications switch (type) {
case NotifType.NEW_BLOG_COMMENT: // Admin Notifications
await this.notificationsService.createNewBlogCommentNotification(recipientId, data as IBlogCommentNotificationData, queryRunner); case NotifType.NEW_BLOG_COMMENT:
break; await this.notificationsService.createNewBlogCommentNotification(
case NotifType.NEW_SERVICE_REVIEW: recipientId,
await this.notificationsService.createNewServiceReviewNotification( data as IBlogCommentNotificationData,
recipientId, queryRunner,
data as IServiceReviewNotificationData, );
queryRunner, break;
); case NotifType.NEW_SERVICE_REVIEW:
break; await this.notificationsService.createNewServiceReviewNotification(
case NotifType.NEW_CUSTOMER: recipientId,
await this.notificationsService.createNewCustomerNotification(recipientId, data as INewCustomerNotificationData, queryRunner); data as IServiceReviewNotificationData,
break; queryRunner,
case NotifType.NEW_SUBSCRIPTION: );
await this.notificationsService.createNewSubscriptionNotification( break;
recipientId, case NotifType.NEW_CUSTOMER:
data as INewSubscriptionNotificationData, await this.notificationsService.createNewCustomerNotification(recipientId, data as INewCustomerNotificationData, queryRunner);
queryRunner, break;
); case NotifType.NEW_SUBSCRIPTION:
break; await this.notificationsService.createNewSubscriptionNotification(
case NotifType.NEW_CRITICISM: recipientId,
await this.notificationsService.createNewCriticismNotification(recipientId, data as INewCriticismNotificationData, queryRunner); data as INewSubscriptionNotificationData,
break; queryRunner,
case NotifType.NEW_TICKET: );
await this.notificationsService.createNewTicketGlobalNotification(recipientId, data as INewTicketNotificationData, queryRunner); break;
break; case NotifType.NEW_CRITICISM:
await this.notificationsService.createNewCriticismNotification(recipientId, data as INewCriticismNotificationData, queryRunner);
break;
case NotifType.NEW_TICKET:
await this.notificationsService.createNewTicketGlobalNotification(recipientId, data as INewTicketNotificationData, queryRunner);
break;
// User Notifications // User Notifications
case NotifType.USER_LOGIN: case NotifType.USER_LOGIN:
await this.notificationsService.createLoginNotification(recipientId, data); await this.notificationsService.createLoginNotification(recipientId, data);
break; break;
case NotifType.ANNOUNCEMENT: case NotifType.ANNOUNCEMENT:
await this.notificationsService.createAnnouncementNotification(recipientId, data as IAnnouncementNotificationData, queryRunner); await this.notificationsService.createAnnouncementNotification(recipientId, data as IAnnouncementNotificationData, queryRunner);
break; break;
// Wallet Notifications // Wallet Notifications
case NotifType.WALLET_CHARGE: case NotifType.WALLET_CHARGE:
await this.notificationsService.createWalletChargeNotification(recipientId, data as IWalletNotificationData, queryRunner); await this.notificationsService.createWalletChargeNotification(recipientId, data as IWalletNotificationData, queryRunner);
break; break;
case NotifType.WALLET_DEDUCTION: case NotifType.WALLET_DEDUCTION:
await this.notificationsService.createWalletDeductionNotification(recipientId, data as IWalletNotificationData, queryRunner); await this.notificationsService.createWalletDeductionNotification(recipientId, data as IWalletNotificationData, queryRunner);
break; break;
// Ticket Notifications // Ticket Notifications
case NotifType.ANSWER_TICKET: case NotifType.ANSWER_TICKET:
await this.notificationsService.createAnswerTicketNotification(recipientId, data as ITicketNotificationData, queryRunner); await this.notificationsService.createAnswerTicketNotification(recipientId, data as ITicketNotificationData, queryRunner);
break; break;
case NotifType.CREATE_TICKET: case NotifType.CREATE_TICKET:
await this.notificationsService.createTicketNotification(recipientId, data as ITicketNotificationData, queryRunner); await this.notificationsService.createTicketNotification(recipientId, data as ITicketNotificationData, queryRunner);
break; break;
case NotifType.ASSIGN_TICKET: case NotifType.ASSIGN_TICKET:
await this.notificationsService.createAssignTicketNotificationForAdmin(recipientId, data as ITicketNotificationData, queryRunner); await this.notificationsService.createAssignTicketNotificationForAdmin(
break; recipientId,
data as ITicketNotificationData,
queryRunner,
);
break;
// Invoice Notifications // Invoice Notifications
case NotifType.CREATE_INVOICE: case NotifType.CREATE_INVOICE:
await this.notificationsService.createInvoiceCreationNotification(recipientId, data as IInvoiceNotificationData, queryRunner); await this.notificationsService.createInvoiceCreationNotification(recipientId, data as IInvoiceNotificationData, queryRunner);
break; break;
case NotifType.BILL_INVOICE_REMINDER: case NotifType.BILL_INVOICE_REMINDER:
await this.notificationsService.createBillInvoiceReminderNotification(recipientId, data as IInvoiceNotificationData, queryRunner); await this.notificationsService.createBillInvoiceReminderNotification(
break; recipientId,
case NotifType.BILL_INVOICE: data as IInvoiceNotificationData,
await this.notificationsService.createBillInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner); queryRunner,
break; );
case NotifType.APPROVE_INVOICE: break;
await this.notificationsService.createApprovedInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner); case NotifType.BILL_INVOICE:
break; await this.notificationsService.createBillInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner);
case NotifType.INVOICE_OVERDUE: break;
await this.notificationsService.createInvoiceOverdueNotification(recipientId, data as IInvoiceNotificationData, queryRunner); case NotifType.APPROVE_INVOICE:
break; await this.notificationsService.createApprovedInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner);
case NotifType.RECURRING_INVOICE: break;
await this.notificationsService.createRecurringInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner); case NotifType.INVOICE_OVERDUE:
break; await this.notificationsService.createInvoiceOverdueNotification(recipientId, data as IInvoiceNotificationData, queryRunner);
break;
case NotifType.RECURRING_INVOICE:
await this.notificationsService.createRecurringInvoiceNotification(recipientId, data as IInvoiceNotificationData, queryRunner);
break;
// Service Notifications // Service Notifications
case NotifType.BLOCK_SERVICE: case NotifType.BLOCK_SERVICE:
await this.notificationsService.createBlockServiceNotification(recipientId, data as ISubscriptionNotificationData, queryRunner); await this.notificationsService.createBlockServiceNotification(recipientId, data as ISubscriptionNotificationData, queryRunner);
break; break;
// Payment Notifications // Payment Notifications
case NotifType.PAYMENT_REMINDER: case NotifType.PAYMENT_REMINDER:
await this.notificationsService.createPaymentReminderNotification(recipientId, data as IPaymentNotificationData, queryRunner); await this.notificationsService.createPaymentReminderNotification(recipientId, data as IPaymentNotificationData, queryRunner);
break; break;
case NotifType.PAYMENT_CANCELLATION: case NotifType.PAYMENT_CANCELLATION:
await this.notificationsService.createPaymentCancellationNotification(recipientId, data as IPaymentNotificationData, queryRunner); await this.notificationsService.createPaymentCancellationNotification(
break; recipientId,
data as IPaymentNotificationData,
queryRunner,
);
break;
default: default:
this.logger.warn(`Unknown notification type: ${type}`); this.logger.warn(`Unknown notification type: ${type}`);
}
await queryRunner.commitTransaction();
clearInterval(heartbeat);
return true;
} catch (error) {
clearInterval(heartbeat);
throw error;
} }
await queryRunner.commitTransaction();
return true;
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
`Failed to process notification: ${error instanceof Error ? error.message : "Unknown error"}`, `Failed to process notification: ${error instanceof Error ? error.message : "Unknown error"}`,