Skip to content

[BE][feat]: FCM 전송 비동기 논블로킹으로 변경#1152

Open
CheChe903 wants to merge 1 commit intodevelop-befrom
feat/1151
Open

[BE][feat]: FCM 전송 비동기 논블로킹으로 변경#1152
CheChe903 wants to merge 1 commit intodevelop-befrom
feat/1151

Conversation

@CheChe903
Copy link
Contributor

@CheChe903 CheChe903 commented Jan 23, 2026

🔗 관련 이슈

📝 작업 내용

주요 변경사항

📸 스크린샷 (Optional)

Summary by CodeRabbit

Release Notes

  • Refactor
    • 알림 메시지 전송 시스템의 내부 처리 방식을 개선했습니다. 공개 API는 변경되지 않았으며, 모든 기능은 이전과 동일하게 작동합니다.

✏️ Tip: You can customize this high-level summary in your review settings.

스레드 점유를 줄이기 위하여 논블로킹 구조로 전환합니다.
@github-actions github-actions bot changed the base branch from main to develop-be January 23, 2026 05:46
@github-actions github-actions bot changed the title Feat/1151 [BE][feat]: FCM 전송 비동기 논블로킹으로 변경 Jan 23, 2026
@github-actions github-actions bot added the BE 백엔드 관련 이슈입니다. label Jan 23, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'tools'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

FcmClient의 FCM 메시지 전송 메커니즘이 동기 방식에서 비동기 방식으로 전환되었습니다. 기존의 동기 FirebaseMessaging 호출을 sendAsync 기반의 ApiFuture로 대체하고, ApiFuturesCallback을 통해 완료/실패를 처리합니다. AlarmException 의존성이 제거되었으며, 통합 에러 로깅을 위해 logFailure 헬퍼 메서드가 추가되었습니다. 공개 메서드의 서명은 유지됩니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


검토 포인트 및 고려사항

1. 반환값 없는 비동기 처리의 의미론적 변화

현재 변경에서 세 개의 공개 메서드가 모두 void를 유지하고 있습니다. 이는 호출자 입장에서 메시지 전송이 성공했는지 실패했는지 직접 알 수 없다는 의미입니다.

문제점:

  • 기존의 동기 호출에서는 예외 발생으로 호출자가 전송 실패를 즉시 감지할 수 있었습니다
  • 비동기 변경 후에는 실패가 콘솔 로그로만 남고, 비즈니스 로직에서 실패 여부를 인지할 수 없습니다
  • 예를 들어, 중요한 알림 전송 후 재시도 로직이 필요한 경우 대응이 불가능합니다

대안 검토:

  • 선택지 1: CompletableFuture 반환으로 호출자가 비동기 완료를 추적 가능하게 함

    • 장점: 호출자가 완료/실패를 선택적으로 처리할 수 있음
    • 단점: 기존 API와의 호환성 깨짐, 호출자 코드 수정 필요
  • 선택지 2: 콜백 함수를 메서드 파라미터로 수용

    • 장점: 실패 시 재시도 등 복잡한 로직을 호출자가 정의 가능
    • 단점: API 복잡도 증가, 초기 변경이 큼
  • 선택지 3: 현재 방식 유지하되, 실패 이벤트를 별도의 관찰 가능한 채널(예: 로그 모니터링, 메트릭)로 노출

    • 장점: 점진적 적용 가능
    • 단점: 실패 감지가 간접적 (로그 파싱 등)

2. MoreExecutors.directExecutor()의 블로킹 위험

ApiFutures.addCallback(..., MoreExecutors.directExecutor())를 사용하면 콜백이 future를 완료한 스레드에서 직접 실행됩니다.

문제점:

  • Firebase 라이브러리가 I/O 스레드에서 응답을 처리한다면, 콜백의 로그 작성도 해당 스레드를 점유합니다
  • 로그 작성이 느리거나 데이터베이스 쿼리 등이 포함될 경우 Firebase의 I/O 스레드를 블로킹할 수 있습니다
  • 대량의 메시지 전송 시 성능 저하 가능성

대안 검토:

  • 선택지 1: 별도의 스레드 풀 사용 (예: Executors.newFixedThreadPool)

    • 장점: 메인 I/O 스레드 보호, 리소스 제어 가능
    • 단점: 스레드 풀 관리 오버헤드 추가
  • 선택지 2: 비동기 로깅 라이브러리 (예: async-logback)로 논블로킹 로그 작성

    • 장점: directExecutor 사용 가능, 로그 손실 최소화
    • 단점: 로깅 라이브러리 학습/유지보수 추가
  • 선택지 3: 콜백을 최소화하고 메트릭 발행만 수행

    • 장점: 콜백 실행 시간 최소화
    • 단점: 상세한 로그 정보 손실

3. 에러 처리의 일방향성

logFailure 메서드에서 실패를 로그만 남기고, 회복 전략(재시도, 폴백, 데드레터 큐 등)이 없습니다.

현재 상황:

  • FirebaseMessagingException인 경우 errorCode 로깅
  • 일반 Throwable인 경우 message 로깅

고려 사항:

  • 재시도 가능 오류(일시적 네트워크 오류)와 불가능한 오류(인증 실패)를 구분해야 할 수 있습니다
  • 특정 토큰/주제에 대한 반복되는 실패는 데이터 정제 대상일 수 있습니다
  • 프로덕션에서 발생하는 FCM 오류들에 대한 모니터링/알림 전략이 필요합니다

제안:
현재 변경이 마무리된 후, 별도의 이슈로 다음을 추진할 것을 권장합니다:

  • 오류 타입별 처리 전략 정의 (재시도 대상 판별 로직)
  • 메트릭 수집 (전송 성공/실패 횟수, errorCode 분포)
  • 알림 임계값 설정 (연속 실패 시 경고)

요약: 이 변경은 FCM 스레드 블로킹 문제를 해결하는 올바른 방향이지만, 비동기 전환에 따른 호출자의 관찰성(observability) 감소와 콜백 실행 환경의 블로킹 위험을 함께 검토하면 더욱 견고한 구현이 될 것입니다.

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning PR 설명이 템플릿 구조는 따르지만, 작업 내용과 주요 변경사항 섹션이 실질적으로 비어있어 구체적인 설명이 부족합니다. 작업 내용 섹션에 개선된 내용을 작성하고, 주요 변경사항에서 동기 호출 제거, ApiFuture 도입, 콜백 기반 처리의 3가지 주요 변경을 구체적으로 설명해주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 PR의 핵심 변경사항(FCM 전송을 비동기 논블로킹으로 변경)을 명확하게 요약하고 있으며, 링크된 이슈 #1151의 제목과도 일치합니다.
Linked Issues check ✅ Passed 코드 변경사항이 FCM 전송을 비동기 논블로킹 구조로 전환하려는 목표를 충족합니다. 동기 try-catch를 ApiFuture와 콜백 기반으로 교체했으며, 공개 메서드 시그니처는 유지되어 기존 호출자에게 영향을 주지 않습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 FCM 전송 방식의 논블로킹 전환이라는 명확한 범위 내에서 진행되었으며, 불필요한 추가 기능이나 무관한 수정은 발견되지 않습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@2Jin1031 2Jin1031 left a comment

Choose a reason for hiding this comment

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

d

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

Labels

BE 백엔드 관련 이슈입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BE][feat]: FCM 전송 비동기 논블로킹으로 변경

2 participants