-
Notifications
You must be signed in to change notification settings - Fork 3
[MERGE] dev->main 병합 #449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MERGE] dev->main 병합 #449
Conversation
[Bug/#433] SSE 에러 로그 + 30초마다 하트비트
WalkthroughSseService에 주기적 하트비트 전송 로직이 추가되었고, 초기 SSE 연결 시 예외 로깅이 보강되었습니다. 하트비트는 30초 간격으로 활성 SSE Emitter 전체에 전송되며, 전송 실패 시 해당 Emitter를 제거합니다. 필요한 스케줄러/IO 예외 관련 import가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant S as Scheduler
participant SS as SseService
participant E1 as SseEmitter A
participant E2 as SseEmitter B
rect rgba(230,245,255,0.6)
note over S,SS: 주기적 하트비트 (30s)
S->>SS: trigger sendHeartbeat()
SS->>E1: send event "heartbeat" {timestamp}
SS->>E2: send event "heartbeat" {timestamp}
end
alt 전송 실패 (IOException)
SS-->>SS: 경고 로그 기록
SS->>SS: 실패한 Emitter 제거
else 전송 성공
SS-->>S: 완료
end
note over SS: 초기 SSE connect 시 예외 발생 시 에러 로그 추가
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/stackpot/stackpot/event/SseService.java (2)
45-56: 초기 연결 예외 로깅 보강 + onError 콜백/기존 연결 정리 제안스택트레이스가 로그에 남도록 Throwable을 함께 전달하고, onError 콜백 및 기존 Emitter 정리를 추가하면 누수/중복 연결을 줄일 수 있습니다.
emitter.onCompletion(() -> emitters.remove(userId)); emitter.onTimeout(() -> emitters.remove(userId)); - emitters.put(userId, emitter); + emitter.onError(ex -> emitters.remove(userId)); + SseEmitter prev = emitters.put(userId, emitter); + if (prev != null) { + prev.complete(); + } try { emitter.send(SseEmitter.event().name("connect").data("연결 완료!")); } catch (Exception e) { - log.error("SSE 연결 중 에러 발생: {}", e.getMessage()); + log.error("SSE 연결 중 에러 발생", e); emitters.remove(userId); }
60-72: 하트비트 전송: 중복 실행 방지, 실패 시 자원 정리, 동시 전송 경합 완화, 로깅 개선
- fixedRate는 실행 시간이 길어질 때 중첩 실행이 발생할 수 있습니다. fixedDelay(+ 초기 지연)와 프로퍼티화 권장.
- 전송 실패 시 completeWithError로 자원 정리.
- 다른 쓰레드의 이벤트 전송과 경합을 줄이기 위해 emitter 단위 동기화 권장.
- 실패 로그에 Throwable 포함.
- @Scheduled(fixedRate = 30000) // 30초마다 실행 + @Scheduled(fixedDelayString = "${sse.heartbeat.delay-ms:30000}", initialDelayString = "${sse.heartbeat.initial-delay-ms:5000}") // 완료 후 지연 public void sendHeartbeat() { emitters.forEach((userId, emitter) -> { try { - emitter.send(SseEmitter.event() - .name("heartbeat") - .data("keep-alive at " + System.currentTimeMillis())); + synchronized (emitter) { + emitter.send(SseEmitter.event() + .name("heartbeat") + .data("keep-alive at " + System.currentTimeMillis())); + } } catch (IOException e) { - log.warn("Failed to send heartbeat to user {}, removing emitter.", userId); - emitters.remove(userId); + log.warn("Heartbeat 전송 실패로 emitter 제거: userId={}", userId, e); + try { + emitter.completeWithError(e); + } finally { + emitters.remove(userId); + } } }); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/main/java/stackpot/stackpot/event/SseService.java(3 hunks)
🔇 Additional comments (3)
src/main/java/stackpot/stackpot/event/SseService.java (3)
23-23: IOException import 적절하트비트 전송 실패 처리에 필요한 예외 타입으로 적절합니다.
60-72: ConcurrentHashMap forEach 중 remove 사용은 안전ConcurrentHashMap에 대해 같은 키를 제거하는 패턴은 안전하며 ConcurrentModificationException을 유발하지 않습니다. 현 접근 방식은 타당합니다.
7-7: 스케줄러 활성화 확인 완료
src/main/java/stackpot/stackpot/StackpotApplication.java13번째 줄에@EnableScheduling이 적용되어 있어@Scheduled기반 하트비트가 정상 작동합니다.- 필요 시 아래 프로퍼티를 추가로 설정해 스케줄러 풀 사이즈나 하트비트를 조정할 수 있습니다(선택 사항):
spring.task.scheduling.pool.sizesse.heartbeat
PR 타입(하나 이상의 PR 타입을 선택해주세요)
반영 브랜치
dev -> main
작업 내용
배포 반영
테스트 결과
ex) 베이스 브랜치에 포함되기 위한 코드는 모두 정상적으로 동작해야 합니다. 결과물에 대한 스크린샷, GIF, 혹은 라이브
Summary by CodeRabbit