Feat: impl STOMP Websocket Redis pub/sub message relay with DTO and constants - #55
Conversation
|
Warning Review limit reached
Next review available in: 15 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough실시간 시험방 응시 상태 DTO와 상태 enum을 추가했다. WebSocket 요청을 Redis 채널에 발행하고, Redis 구독 메시지를 방별 WebSocket 목적지로 전달하는 흐름을 추가했다. Changes실시간 시험방 메시징
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.java`:
- Around line 20-29: Update RoomRealtimeController.sendMessage to use the
`@DestinationVariable` roomId and authenticated Principal identity instead of
request-body identifiers, ignoring or removing duplicate roomId and
client-provided userId values. Before redisMessagePublisher.publish, validate
that the authenticated user has access to the specified room, then construct
RealtimeMessageResponse with the trusted identities.
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.java`:
- Around line 14-20: Apply request validation to RealtimeMessageRequest by
enforcing non-null status and a non-negative solvedCount, then annotate the
controller sendMessage() request parameter with `@Valid`. Ensure validation
failures from STOMP messages are converted to the existing Common
BusinessException so the established WebSocket exception-handling flow is used.
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java`:
- Around line 23-32: Update RedisMessagePublisher.publish so failures from
objectMapper.writeValueAsString or redisTemplate.convertAndSend are not
swallowed after logging. Wrap and rethrow them as the project’s domain
exception, then verify the shared STOMP exception handler converts that
exception into an error frame or explicit failure response. Add coverage for
both Redis connection failures and JSON serialization failures.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7976a024-ecfd-46b1-a04e-12fd13c60945
📒 Files selected for processing (8)
momogo-realtime/src/main/java/com/momogo/realtime/config/RedisPubSubConfig.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/constant/WebSocketConstants.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/response/RealtimeMessageResponse.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/type/RoomRealtimeStatus.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessageSubscriber.java
…eviews for realtime websocket
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@momogo-core/src/main/java/com/momogo/core/common/exception/RealtimeErrorCode.java`:
- Around line 11-16: The REDIS_PUBLISH_FAILED error code is currently applied to
both JSON serialization and Redis publish failures. Update
RedisMessagePublisher.publish() to separate ObjectMapper.writeValueAsString()
error handling from redisTemplate.convertAndSend(), using REDIS_PUBLISH_FAILED
only for the latter and mapping serialization failures to an appropriate
separate error code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 14953a02-b89d-481d-9bd3-7f1a59b2273b
📒 Files selected for processing (5)
momogo-core/src/main/java/com/momogo/core/common/exception/RealtimeErrorCode.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/response/RealtimeMessageResponse.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java
🚧 Files skipped from review as they are similar to previous changes (3)
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.java
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.java
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java
… RedisMessagerPublisher
idktomorrow
left a comment
There was a problem hiding this comment.
큰 문제 없어 보입니다! 작성하시느라 고생 많으셨습니다 ❤️
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java (1)
18-20: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winRedis Pub/Sub wire format은 한 번만 직렬화하세요.
RedisConfig가RedisTemplate<String, Object>의 value serializer를GenericJackson2JsonRedisSerializer로 설정하지만, subscriber는 기본MessageListenerAdapter만 사용하므로 수신된 JSON 문자열이 다시 Jackson serializer로 직렬화될 수 있습니다.RedisMessageSubscriber.handleMessage(String)가objectMapper.readValue()를 호출해 역직렬화하기 때문에 subscriber에서는UnexpectedException, publisher에서는 실제 구독자가 원본 JSON을 받을 수 있습니다. 이 채널에서는StringRedisTemplate(String, String, StringRedisSerializer)로 발행/수신하거나MessageListenerAdapter의 serializer를StringRedisSerializer로 명시하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java` around lines 18 - 20, Redis Pub/Sub 메시ğinin tek kez JSON olarak serileştirilmesini sağlayın. RedisMessagePublisher’ın RedisTemplate yapılandırmasını RedisConfig ile uyumlu olacak şekilde StringRedisTemplate veya StringRedisSerializer kullanacak biçimde güncelleyin ve RedisMessageSubscriber ile MessageListenerAdapter’ın da StringRedisSerializer üzerinden ham JSON almasını sağlayın; RedisMessageSubscriber.handleMessage(String) mevcut objectMapper.readValue() akışını korumalıdır.
🧹 Nitpick comments (1)
momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java (1)
33-33: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win운영 로그에서 payload 원문을 제거하세요.
Line 33과 Line 42는 전체
messagePayload를 ERROR 로그에 기록합니다. Line 39도 전체jsonMessage를 INFO 로그에 기록합니다. 실시간 메시지가 빈번하면 로그량이 증가하고, room/member 식별자 또는 응시 상태가 노출될 수 있습니다.topic, room ID, correlation ID처럼 안전한 메타데이터만 기록하세요. 본문이 필요하면 redaction 후 DEBUG 레벨로 기록하세요. PMD 경고를 없애기 위해
e를 제거하지 마세요. SLF4J는 마지막Throwable을 예외 정보로 처리할 수 있습니다. (slf4j.org)- log.error("[Redis Publisher] JSON 직렬화 실패 - payload: {}", messagePayload, e); + log.error("[Redis Publisher] JSON 직렬화 실패", e); - log.error("[Redis Publisher] Redis 메시지 전송 실패 - payload: {}", messagePayload, e); + log.error("[Redis Publisher] Redis 메시지 전송 실패", e);Also applies to: 39-39, 42-42
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java` at line 33, Update the logging in RedisMessagePublisher so ERROR and INFO messages no longer include the full messagePayload or jsonMessage; retain only safe metadata such as topic, room ID, or correlation ID, and keep the trailing exception argument e in serialization error logging so SLF4J preserves stack-trace details. If payload diagnostics are required, emit a redacted version only at DEBUG level.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@momogo-realtime/src/main/java/com/momogo/realtime/config/RedisPubSubConfig.java`:
- Around line 43-46: RedisMessageListenerContainer의 메시지 처리와 구독 연결 유지가 동일한
executor를 공유하지 않도록 RedisPubSubConfig의 createThreadPoolTaskExecutor 및 bean 구성을
분리하세요. publish 처리용 messageTaskExecutor와 구독 유지용 subscriptionExecutor를 각각 생성·주입하고,
setTaskExecutor에는 전자를 setSubscriptionExecutor에는 후자를 지정하세요.
- Around line 55-63: Register the ThreadPoolTaskExecutor created by
createThreadPoolTaskExecutor as a Spring `@Bean` so its lifecycle is managed
during application shutdown. Update redisMessageListenerContainer(...) to accept
and use this executor bean instead of creating it only through the private
method, preserving the existing redis-listener-* configuration.
- Around line 43-45: Update RedisPubSubConfig so Redis messages for the same
room or session are processed serially instead of using the current shared
parallel taskExecutor, preserving ENTER/PROGRESS/SUBMIT/LEAVE ordering while
retaining concurrency across independent rooms or sessions. Configure the
RedisMessageListenerContainer task executor accordingly; do not change unrelated
messaging behavior.
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java`:
- Around line 39-41: Update the publishing flow around
RedisTemplate.convertAndSend to capture its returned subscriber count, treat
null or zero as REDIS_PUBLISH_FAILED (or record an equivalent explicit failure
metric), and emit the success log only after a positive result is received.
Preserve the existing exception handling for thrown failures.
---
Outside diff comments:
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java`:
- Around line 18-20: Redis Pub/Sub 메시ğinin tek kez JSON olarak
serileştirilmesini sağlayın. RedisMessagePublisher’ın RedisTemplate
yapılandırmasını RedisConfig ile uyumlu olacak şekilde StringRedisTemplate veya
StringRedisSerializer kullanacak biçimde güncelleyin ve RedisMessageSubscriber
ile MessageListenerAdapter’ın da StringRedisSerializer üzerinden ham JSON
almasını sağlayın; RedisMessageSubscriber.handleMessage(String) mevcut
objectMapper.readValue() akışını korumalıdır.
---
Nitpick comments:
In
`@momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.java`:
- Line 33: Update the logging in RedisMessagePublisher so ERROR and INFO
messages no longer include the full messagePayload or jsonMessage; retain only
safe metadata such as topic, room ID, or correlation ID, and keep the trailing
exception argument e in serialization error logging so SLF4J preserves
stack-trace details. If payload diagnostics are required, emit a redacted
version only at DEBUG level.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1975472f-c360-4394-8752-d940366f2c86
📒 Files selected for processing (6)
momogo-core/src/main/java/com/momogo/core/common/exception/RealtimeErrorCode.javamomogo-realtime/src/main/java/com/momogo/realtime/config/RedisPubSubConfig.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessagePublisher.javamomogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessageSubscriber.java
💤 Files with no reviewable changes (1)
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/dto/request/RealtimeMessageRequest.java
🚧 Files skipped from review as they are similar to previous changes (2)
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/controller/RoomRealtimeController.java
- momogo-realtime/src/main/java/com/momogo/realtime/websocket/redis/RedisMessageSubscriber.java
작업 내용
RealtimeMessageRequest,RealtimeMessageResponse), 응시 상태 Enum (RoomRealtimeStatus), 및 상수 클래스 (WebSocketConstants) 구축RoomRealtimeController) 및 Redis 메시지 발행/수신자 (RedisMessagePublisher,RedisMessageSubscriber) 연동변경 사항
RedisPubSubConfig.java:"room-realtime-channel") 및RedisMessageListenerContainer빈 정의RedisMessagePublisher.java&RedisMessageSubscriber.java:/sub/rooms/{roomId}목적지 구독자들에게 브로드캐스팅하도록 구현WebSocketConstants.java:"/sub/rooms/") 상수를 추출하여 캡슐화 관리RealtimeMessageRequest,RealtimeMessageResponse(record 및 정적 팩토리 메소드 적용)RoomRealtimeStatus(ENTER, PROGRESS, SUBMIT, LEAVE 응시 상태 Enum)체크리스트
참고 사항
클라이언트 STOMP 요청 (/pub/rooms/{roomId}/send)➔RoomRealtimeController➔RedisMessagePublisher➔Redis Pub/Sub➔RedisMessageSubscriber➔SimpMessagingTemplate (/sub/rooms/{roomId}) 브로드캐스트JwtChannelInterceptor가 전담관련 이슈
Summary by CodeRabbit