Skip to content

Comments

[REFACTOR] 알림 시스템 Outbox 패턴 + RabbitMQ로 전환#377

Merged
1000hyehyang merged 8 commits intodevfrom
refactor/348-notification
Feb 11, 2026
Merged

[REFACTOR] 알림 시스템 Outbox 패턴 + RabbitMQ로 전환#377
1000hyehyang merged 8 commits intodevfrom
refactor/348-notification

Conversation

@1000hyehyang
Copy link
Member

Summary

알림 발송 방식을 DB 폴링에서 Outbox 패턴 + RabbitMQ 기반 비동기 구조로 전환했습니다.
Notification/Delivery/Outbox를 한 트랜잭션에 원자적으로 저장하고, 별도 Publisher가 MQ로 발행한 뒤 Consumer가 FCM/Email을 보내도록 하여, 트랜잭션 안전성·메시지 유실 방지·중복 발송 방지를 보강했습니다.

Changes

아키텍처

  • NotificationService: Notification + NotificationDelivery(PENDING) + NotificationOutbox(PENDING)를 단일 TX에 저장. MQ 발행은 하지 않음.
  • NotificationOutboxPublisher (5초 주기): PENDING Outbox 조회 → claim → RabbitMQ 발행 → SENT/FAILED 기록. @Transactional 없이 MQ 발행이 TX 밖에서 실행되도록 유지.
  • NotificationDeliveryConsumer: MQ 수신 → delivery claim → FCM/Email 발송 → 결과 기록. 일시 오류는 ACK 후 recordFailure + createRetryOutboxIfAbsent로 재발행, **poison(영구 오류)**만 NACK → DLQ.
  • NotificationRecoveryScheduler: stuck IN_PROGRESS/SENDING 복구, RETRY 재발행, 고아 PENDING 복구, 완료 Outbox 7일 후 삭제.

신규/변경 컴포넌트

  • 도메인: NotificationOutbox 엔티티, OutboxStatus enum. DeliveryStatusRETRY 추가.
  • 레포: NotificationOutboxRepository (findPending, claim, markSent, markPublishFailed 원자적 업데이트, createRetryOutboxIfAbsent용 조회). NotificationDeliveryRepositoryfindOrphanedPendingDeliveries, findRetryableDeliveries 등.
  • 서비스: NotificationOutboxService (Outbox TX 경계), NotificationDeliveryClaimService (Delivery claim/결과 기록). NotificationService는 create 시 Outbox까지 한 TX에 저장.
  • 인프라: RabbitMqConfig (exchange, queue, DLQ, Manual ACK, JSON). NotificationDeliveryMessage DTO. NotificationOutboxPublisher, NotificationDeliveryConsumer, NotificationRecoveryScheduler.

예외/복구 정책

  • Consumer: isTransient(e) = DataAccessException, SocketTimeoutException, ConnectException, UnknownHostException. ShutdownSignalException은 제외(컨테이너 재연결 담당).
  • 일시 오류: ACK + recordFailure + createRetryOutboxIfAbsent. 재시도 스케줄 실패 시에도 ACK( DLQ 오염 방지 ) → stuck IN_PROGRESS는 recoverStuckDeliveries가 RETRY로 복구.
  • Poison: 파싱 실패·역직렬화 등 → NACK(requeue=false) → DLQ.
  • Outbox 발행 실패: markPublishFailed에서 retry_count 증가 + status(PENDING/FAILED)를 JPQL CASE로 원자 처리. enum은 파라미터로 전달(provider-agnostic).

기타

  • createRetryOutboxIfAbsent: delivery가 PENDING/RETRY일 때만 Outbox 생성(FAILED 제외). 동일 delivery에 PENDING/SENDING Outbox 있으면 skip.
  • 문서: notification-architecture.md 신규, notification-feature-prd.md·notification-erd.md·notification-deployment-guide.md·notification-integration-guide.md 업데이트. 원자성 문구 정정, DLQ/ACK 정책, 예외 분기 반영.
  • 스크립트: create_notification_outbox_table.sql 추가. create_notification_delivery_table.sql에 RETRY 상태 주석 반영.

Type of Change

  • Bug fix (기존 기능에 영향을 주지 않는 버그 수정)
  • New feature (기존 기능에 영향을 주지 않는 새로운 기능 추가)
  • Breaking change (기존 기능에 영향을 주는 수정)
  • Refactoring (기능 변경 없는 코드 개선)
  • Documentation (문서 수정)
  • Chore (빌드, 설정 등 기타 변경)
  • Release (develop → main 배포)

Related Issues

Closes #348

참고 사항

  • 배포 시: RabbitMQ 연결 정보(RABBITMQ_URL, RABBITMQ_MQ_PORT, RABBITMQ_USERNAME, RABBITMQ_PASSWORD) 설정 필요.
  • DB 마이그레이션: scripts/sql/create_notification_outbox_table.sql 실행 필요. 기존 notification_delivery는 RETRY 상태 사용을 위해 스키마 호환(기존 컬럼 유지).

@1000hyehyang 1000hyehyang self-assigned this Feb 11, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @1000hyehyang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 Pull Request는 알림 시스템의 근본적인 아키텍처를 개선하여, 기존의 DB 폴링 방식에서 Outbox 패턴과 RabbitMQ를 활용한 비동기 메시징 시스템으로 전환합니다. 이러한 변화는 알림 발송의 안정성과 신뢰성을 크게 향상시키며, 특히 데이터 일관성 보장, 메시지 유실 방지, 그리고 시스템 부하 분산에 중점을 둡니다. 새로운 구조는 알림 생성과 실제 발송 과정을 분리하여 시스템의 견고성을 높이고, 다양한 오류 상황에 대한 복구 메커니즘을 제공합니다.

Highlights

  • 알림 시스템 아키텍처 전환: 알림 발송 방식을 기존의 DB 폴링에서 Outbox 패턴과 RabbitMQ 기반의 비동기 구조로 전환하여 시스템의 견고성과 신뢰성을 강화했습니다.
  • 원자적 트랜잭션 보장: Notification, NotificationDelivery, NotificationOutbox 엔티티를 단일 트랜잭션 내에서 원자적으로 저장하여 데이터 일관성을 보장합니다.
  • 비동기 메시징 컴포넌트 도입: RabbitMQ로 메시지를 발행하는 NotificationOutboxPublisher와 FCM/Email 발송을 처리하는 NotificationDeliveryConsumer를 도입하여 알림 발송 과정을 분리했습니다.
  • 강화된 예외 처리 및 복구 메커니즘: 일시적 오류는 재시도를 위해 ACK 후 재발행하고, 영구적 오류는 NACK 후 DLQ로 보내는 정책을 구현했으며, Stuck 상태의 Delivery 및 Outbox를 복구하는 스케줄러를 추가했습니다.
  • 새로운 도메인 및 인프라 컴포넌트: NotificationOutbox 엔티티, OutboxStatus 열거형, DeliveryStatusRETRY 상태를 추가하고, 관련 서비스, 리포지토리, 메시징 인프라(RabbitMqConfig 등)를 신규 도입했습니다.
Changelog
  • src/main/java/com/example/RealMatch/notification/application/service/NotificationDeliveryClaimService.java
    • 알림 배달 상태를 클레임하고, 성공 또는 실패를 기록하는 새로운 서비스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/application/service/NotificationDeliveryProcessor.java
    • 기존의 알림 배달 처리 로직을 담당하던 서비스를 제거했습니다.
  • src/main/java/com/example/RealMatch/notification/application/service/NotificationOutboxService.java
    • Outbox 엔티티의 DB 연산을 관리하고 트랜잭션 경계를 제공하는 새로운 서비스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/application/service/NotificationService.java
    • 알림 생성 시 NotificationDelivery와 함께 NotificationOutbox를 원자적으로 저장하도록 로직을 수정했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/NotificationDelivery.java
    • 알림 배달 상태 전이 로직을 업데이트하고, IN_PROGRESS 상태 전환 메서드를 제거하며 RETRY 상태를 반영했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/NotificationOutbox.java
    • Outbox 패턴 구현을 위한 새로운 엔티티를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/enums/DeliveryStatus.java
    • 알림 배달 상태에 RETRY를 추가하고, 기존 상태 설명을 업데이트했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/enums/OutboxStatus.java
    • NotificationOutbox의 MQ 발행 상태를 정의하는 새로운 열거형을 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/repository/NotificationDeliveryRepository.java
    • Delivery 상태 클레임, 재시도 가능한 Delivery 조회, Stuck Delivery 복구, 고아 PENDING Delivery 조회 등 새로운 쿼리 메서드를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/repository/NotificationOutboxRepository.java
    • Outbox 엔티티를 위한 새로운 리포지토리를 추가하여 PENDING Outbox 조회, 클레임, 발행 성공/실패 기록, Stuck Outbox 복구, 완료된 Outbox 삭제 등의 기능을 제공합니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/messaging/NotificationDeliveryConsumer.java
    • RabbitMQ 메시지를 수신하여 알림을 발송하고 결과를 기록하는 새로운 Consumer 컴포넌트를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/messaging/NotificationDeliveryMessage.java
    • RabbitMQ를 통해 전달되는 알림 배달 메시지 DTO를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/messaging/NotificationOutboxPublisher.java
    • 주기적으로 PENDING 상태의 Outbox를 조회하여 RabbitMQ로 메시지를 발행하는 새로운 Publisher 컴포넌트를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/messaging/NotificationRecoveryScheduler.java
    • Stuck 상태의 Delivery 및 Outbox 복구, 재시도 Delivery 재처리, 고아 Delivery 복구, 완료된 Outbox 정리 등을 담당하는 새로운 스케줄러를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/messaging/RabbitMqConfig.java
    • RabbitMQ Exchange, Queue, DLQ, Binding, MessageConverter 및 ListenerContainerFactory를 설정하는 구성 클래스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/sender/NotificationChannelSender.java
    • 인터페이스 주석에서 NotificationDeliveryProcessor를 NotificationDeliveryConsumer로 업데이트했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/worker/NotificationDeliveryWorker.java
    • 기존의 알림 배달 워커 컴포넌트를 제거했습니다.
  • src/test/java/com/example/RealMatch/notification/application/event/NotificationEventListenerIntegrationTest.java
    • 알림 이벤트 리스너 통합 테스트 파일을 제거했습니다.
  • src/test/java/com/example/RealMatch/notification/application/service/NotificationChannelResolverTest.java
    • 알림 채널 리졸버 단위 테스트 파일을 제거했습니다.
  • src/test/java/com/example/RealMatch/notification/application/service/NotificationMessageTemplateServiceTest.java
    • 알림 메시지 템플릿 서비스 단위 테스트 파일을 제거했습니다.
Activity
  • 이 Pull Request는 아직 어떠한 인간 활동(댓글, 리뷰 등)도 기록되지 않았습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

알림 시스템을 DB 폴링 방식에서 Outbox 패턴과 RabbitMQ를 사용하는 비동기 구조로 전환하는 대규모 리팩터링을 진행해주셨네요. 트랜잭션 안정성과 메시지 유실 방지를 위한 고민이 돋보이는 훌륭한 아키텍처 개선입니다. 발행, 소비, 복구 로직 전반에 걸쳐 시스템 안정성을 높이기 위한 설계가 인상적입니다.

다만, 한 가지 매우 중요한 우려 사항이 있습니다. 알림 기능과 관련된 모든 테스트 코드(NotificationEventListenerIntegrationTest, NotificationChannelResolverTest, NotificationMessageTemplateServiceTest)가 삭제되었고, 새로 추가된 테스트가 없습니다. Outbox 패턴과 메시지 큐를 사용하는 비동기 아키텍처는 복잡성이 높고 잠재적인 실패 시나리오가 많아 철저한 테스트가 필수적입니다. 현재 새로운 핵심 로직들(Outbox 발행, 메시지 소비, 다양한 복구 스케줄링 등)이 테스트로 검증되지 않은 상태로 남아있습니다. 이는 시스템 안정성에 큰 위협이 될 수 있으므로, 단위 테스트와 더불어 Testcontainers 등을 활용한 통합 테스트를 반드시 추가하시는 것을 강력히 권장합니다.

그 외 몇 가지 코드 개선점은 향후 리팩토링 과제로 이월될 수 있는 제안으로 남겼습니다. 확인 부탁드립니다.

@1000hyehyang
Copy link
Member Author

Code Review

알림 시스템을 DB 폴링 방식에서 Outbox 패턴과 RabbitMQ를 사용하는 비동기 구조로 전환하는 대규모 리팩터링을 진행해주셨네요. 트랜잭션 안정성과 메시지 유실 방지를 위한 고민이 돋보이는 훌륭한 아키텍처 개선입니다. 발행, 소비, 복구 로직 전반에 걸쳐 시스템 안정성을 높이기 위한 설계가 인상적입니다.

다만, 한 가지 매우 중요한 우려 사항이 있습니다. 알림 기능과 관련된 모든 테스트 코드(NotificationEventListenerIntegrationTest, NotificationChannelResolverTest, NotificationMessageTemplateServiceTest)가 삭제되었고, 새로 추가된 테스트가 없습니다. Outbox 패턴과 메시지 큐를 사용하는 비동기 아키텍처는 복잡성이 높고 잠재적인 실패 시나리오가 많아 철저한 테스트가 필수적입니다. 현재 새로운 핵심 로직들(Outbox 발행, 메시지 소비, 다양한 복구 스케줄링 등)이 테스트로 검증되지 않은 상태로 남아있습니다. 이는 시스템 안정성에 큰 위협이 될 수 있으므로, 단위 테스트와 더불어 Testcontainers 등을 활용한 통합 테스트를 반드시 추가하시는 것을 강력히 권장합니다.

그 외 몇 가지 코드 개선점은 향후 리팩토링 과제로 이월될 수 있는 제안으로 남겼습니다. 확인 부탁드립니다.

@gemini-code-assist 나중에 테스트코드 추가하려고! 다른 코드 리뷰 제안 없을까? /gemini review

@1000hyehyang
Copy link
Member Author

/gemini review

@1000hyehyang 1000hyehyang merged commit ea1e863 into dev Feb 11, 2026
1 check passed
@1000hyehyang 1000hyehyang deleted the refactor/348-notification branch February 11, 2026 12:57
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

알림 시스템을 DB 폴링에서 Outbox 패턴과 RabbitMQ 기반의 비동기 구조로 전환하는 대규모 리팩토링을 진행해주셨네요. PR 설명과 코드를 보니 트랜잭션 안전성, 메시지 유실 방지, 멱등성 등 분산 시스템에서 발생할 수 있는 여러 문제에 대해 깊이 고민하고 견고하게 구현하신 점이 인상적입니다. 특히 Publisher와 Consumer에서의 claim 로직, 다양한 시나리오에 대비한 복구 스케줄러, 원자적 DB 업데이트를 활용한 상태 관리 등은 매우 훌륭합니다.

다만 한 가지 우려되는 점은 이렇게 중요하고 복잡한 아키텍처 변경에 대한 테스트 코드가 보이지 않는다는 것입니다. 기존 테스트 코드(NotificationEventListenerIntegrationTest 등)가 삭제되었는데, 새로운 Outbox, Publisher, Consumer, 복구 로직에 대한 단위 테스트나 통합 테스트가 추가되지 않았습니다. 특히 Consumer의 일시적/영구적 오류 처리 로직이나 동시성 이슈를 방지하는 claim 로직 등은 테스트를 통해 안정성을 반드시 검증해야 합니다. 프로덕션 환경의 안정성을 위해 새로운 아키텍처에 대한 테스트 코드를 추가하는 것을 강력히 권장합니다.


// RabbitMQ
implementation 'com.rabbitmq:amqp-client'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

RabbitMQ 테스트 의존성을 추가해주신 것은 좋지만, 이번 PR에서 리팩토링된 중요 로직에 대한 테스트 코드가 보이지 않습니다. 특히 NotificationDeliveryConsumer의 오류 처리, NotificationOutboxPublisher의 발행 로직, NotificationRecoveryScheduler의 복구 시나리오 등은 시스템의 안정성과 직결되므로 테스트 커버리지를 확보하는 것이 매우 중요합니다.

spring-rabbit-test@RabbitListenerTest 등을 활용하면 RabbitMQ 컴포넌트를 효과적으로 테스트할 수 있습니다. 새로운 아키텍처의 안정성을 보장하기 위해 테스트 코드를 추가해주시길 바랍니다.

Comment on lines +50 to +85
@Transactional
public void markSent(UUID deliveryId, String providerMessageId) {
NotificationDelivery delivery = deliveryRepository.findById(deliveryId).orElse(null);
if (delivery == null) {
LOG.warn("[DeliveryClaim] Delivery not found for markSent. deliveryId={}", deliveryId);
return;
}
delivery.markAsSent(providerMessageId);
LOG.debug("[DeliveryClaim] Marked SENT. deliveryId={}, providerId={}", deliveryId, providerMessageId);
}

/** 일시적 실패. attemptCount 기준 RETRY(backoff) 또는 FAILED. */
@Transactional
public void recordFailure(UUID deliveryId, String reason) {
NotificationDelivery delivery = deliveryRepository.findById(deliveryId).orElse(null);
if (delivery == null) {
LOG.warn("[DeliveryClaim] Delivery not found for recordFailure. deliveryId={}", deliveryId);
return;
}
delivery.recordFailure(reason);
LOG.warn("[DeliveryClaim] Recorded failure. deliveryId={}, attempt={}, newStatus={}",
deliveryId, delivery.getAttemptCount(), delivery.getStatus());
}

/** 영구 실패(잘못된 토큰, 미존재 이메일 등). 재시도 불가. */
@Transactional
public void markPermanentlyFailed(UUID deliveryId, String reason) {
NotificationDelivery delivery = deliveryRepository.findById(deliveryId).orElse(null);
if (delivery == null) {
LOG.warn("[DeliveryClaim] Delivery not found for permanent failure. deliveryId={}", deliveryId);
return;
}
delivery.markAsPermanentlyFailed(reason);
LOG.warn("[DeliveryClaim] Marked PERMANENTLY FAILED. deliveryId={}, reason={}", deliveryId, reason);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

markSent, recordFailure, markPermanentlyFailed 세 메서드에서 deliveryRepository.findById(...)로 엔티티를 조회하고 null 체크를 하는 로직이 중복되고 있습니다. 코드 유지보수성을 높이기 위해 이 중복 로직을 별도의 private 헬퍼 메서드로 추출하는 것을 고려해볼 수 있습니다.

예를 들어, 다음과 같이 Consumer<NotificationDelivery>를 인자로 받는 헬퍼 메서드를 만들어 사용할 수 있습니다.

private void updateDelivery(UUID deliveryId, String action, Consumer<NotificationDelivery> updater) {
    NotificationDelivery delivery = deliveryRepository.findById(deliveryId).orElse(null);
    if (delivery == null) {
        LOG.warn("[DeliveryClaim] Delivery not found for {}. deliveryId={}", action, deliveryId);
        return;
    }
    updater.accept(delivery);
}

@Transactional
public void markSent(UUID deliveryId, String providerMessageId) {
    updateDelivery(deliveryId, "markSent", delivery -> {
        delivery.markAsSent(providerMessageId);
        LOG.debug("[DeliveryClaim] Marked SENT. deliveryId={}, providerId={}", deliveryId, providerMessageId);
    });
}

// recordFailure, markPermanentlyFailed도 유사하게 변경

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 기존 DB 폴링 방식의 알림 시스템을 Outbox 패턴과 RabbitMQ 기반의 비동기 구조로 전환하는 중요한 리팩토링입니다. 트랜잭션 안전성, 메시지 유실 방지, 중복 발송 방지를 위한 설계가 매우 훌륭하며, 특히 원자적 DB 연산과 상세한 장애 복구 로직 등 구현의 완성도가 높습니다.

다만, 몇 가지 점을 지적하고 싶습니다.

  • 테스트 부재 (심각도: critical): 가장 우려되는 점은 새로운 아키텍처에 대한 테스트 코드가 없다는 것입니다. NotificationEventListenerIntegrationTest를 포함한 여러 테스트 파일이 삭제되었지만, NotificationDeliveryConsumer, NotificationOutboxPublisher 등 핵심 컴포넌트의 동작을 검증하는 새로운 테스트가 추가되지 않았습니다. 알림 시스템과 같은 핵심 기능의 대규모 리팩토링에는 안정성을 보장하기 위한 충분한 테스트가 반드시 동반되어야 합니다. 배포 전에 통합 테스트 및 단위 테스트를 추가하여 새로운 아키텍처의 각 부분이 예상대로 동작하는지, 특히 다양한 예외 상황(메시지 유실, 중복 처리, DLQ 등)을 올바르게 처리하는지 검증해야 합니다.

  • 일관성 개선: NotificationDeliveryConsumer에서 일시적인 오류를 처리하는 방식에 약간의 비일관성이 있습니다. 자세한 내용은 파일 리뷰 코멘트를 참고해 주세요.

전반적으로 훌륭한 리팩토링이며, 테스트 코드 보강이 이루어진다면 더욱 안정적인 시스템이 될 것이라 확신합니다.


try {
claimService.recordFailure(deliveryId, e.getMessage());
outboxService.createRetryOutboxIfAbsent(deliveryId, notificationId, channelEnum);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

handleTransientError 메서드에서 일시적 오류 발생 시 recordFailure 호출 후 즉시 createRetryOutboxIfAbsent를 호출하고 있습니다. 이는 processMessage 내부에서 외부 API 호출 시 발생하는 일시적 오류를 처리하는 방식(스케줄러가 RETRY 상태를 감지하여 Outbox를 생성)과 다소 비일관적입니다.

오류 처리 전략을 일관되게 가져가고 Consumer의 책임을 줄이기 위해, 여기서 createRetryOutboxIfAbsent 호출을 제거하고 모든 재시도 로직을 NotificationRecoveryScheduler에 위임하는 것을 제안합니다. 이렇게 하면 모든 RETRY 상태의 DeliveryreprocessRetryDeliveries 스케줄러에 의해 일관된 방식으로 처리되어 코드의 예측 가능성과 유지보수성이 향상됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 알림 시스템 RabbitMQ 적용

1 participant