feat: Redis 멱등성 키, 지연 큐 인프라 구축 - #68
Conversation
|
Warning Review limit reached
Next review available in: 39 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. 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)
📝 WalkthroughWalkthroughRedis 연결 설정과 멱등성 키 저장소를 추가하고, 원자적 Redis 지연 큐와 주기적 폴러를 구성했다. Testcontainers 기반 통합 테스트와 integration 태그별 테스트 실행 설정도 추가했다. ChangesRedis 인프라 및 지연 처리
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant DelayedQueuePoller
participant DelayedQueue
participant Redis
participant DelayedJobHandler
DelayedQueuePoller->>DelayedQueue: notification 큐의 due payload 조회
DelayedQueue->>Redis: due payload 원자적 조회 및 삭제
Redis-->>DelayedQueue: payload 목록 반환
DelayedQueue-->>DelayedQueuePoller: due payload 전달
DelayedQueuePoller->>DelayedJobHandler: payload별 handle 호출
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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: 1
🧹 Nitpick comments (4)
src/main/java/com/piuda/callcare/global/config/redis/RedisConfig.java (1)
49-58: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win헬스 체크
ping()이 기동을 블로킹할 수 있다.수동으로 생성한
LettuceConnectionFactory에는 커맨드 타임아웃이 설정되어 있지 않다. Redis가 접근 불가능한 경우connection.ping()이 무기한 또는 기본 타임아웃(최대 60s)까지 블로킹되어 애플리케이션 시작이 지연된다.ApplicationRunner는 컨텍스트 초기화 후 실행되므로 준비 상태(readiness)가 늦어진다.위 제안대로 자동 구성으로 전환하고
spring.data.redis.timeout을 짧게(예: 2s) 설정하거나, 수동 구성을 유지한다면LettuceClientConfiguration.builder().commandTimeout(Duration.ofSeconds(2)).build()를 적용한다.🤖 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 `@src/main/java/com/piuda/callcare/global/config/redis/RedisConfig.java` around lines 49 - 58, Update the Redis connection configuration used by LettuceConnectionFactory to apply a short command timeout, such as 2 seconds, via LettuceClientConfiguration.builder().commandTimeout(...).build(), or switch to the existing Spring Boot Redis auto-configuration with spring.data.redis.timeout set accordingly. Ensure redisConnectionHealthCheck’s connection.ping() cannot block application startup indefinitely.src/main/java/com/piuda/callcare/global/config/redis/DelayedQueue.java (1)
36-40: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueLua
unpack()스택 한계(~8000)에 유의.
unpack(due)는 Lua 5.1 스택 크기(약 8000)까지만 안전한다. 기본DEFAULT_POLL_LIMIT=100이면 문제없지만,pollDue(queueKey, limit)의 공개 API에서 큰 limit을 전달하면 스크립트 에러가 발생할 수 있다.limit 상한을 캡하거나, 큰 limit이 필요하면 루프로
ZREM을 수행하는 방안을 고려한다.🤖 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 `@src/main/java/com/piuda/callcare/global/config/redis/DelayedQueue.java` around lines 36 - 40, Update the RedisScript used by pollDue to avoid calling unpack(due) with an unbounded public limit; either cap the accepted poll limit to the Lua-safe range or replace the bulk ZREM with a loop that removes each due item safely. Preserve polling and removal behavior for the default limit and large requested limits.src/test/java/com/piuda/callcare/global/config/redis/DelayedQueueIT.java (1)
22-39: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
Thread.sleep기반 시간 대기 테스트가 CI 환경에서 플래키할 수 있습니다.두 테스트 모두 500ms 지연/TTL에 대해
Thread.sleep(700)으로 200ms 마진만 두고 있습니다. CI 환경 부하 시 마진이 부족할 수 있습니다.
src/test/java/com/piuda/callcare/global/config/redis/DelayedQueueIT.java#L22-L39:Thread.sleep(700)→ Awaitility 기반 폴링 대기 또는 마진 증가(예: 1500ms) 권장src/test/java/com/piuda/callcare/global/config/redis/IdempotencyKeyStoreIT.java#L32-L45: 동일하게Thread.sleep(700)→ Awaitility 또는 마진 증가 권장Awaitility를 사용하면 정확한 타이밍 없이 조건 충족 시점까지 대기하므로 플래키니스를 줄일 수 있습니다:
await().atMost(2, SECONDS).untilAsserted(() -> assertThat(delayedQueue.pollDue(QUEUE)).containsExactly(payload));🤖 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 `@src/test/java/com/piuda/callcare/global/config/redis/DelayedQueueIT.java` around lines 22 - 39, Replace fixed Thread.sleep(700) waits with Awaitility-based condition polling in DelayedQueueIT.java lines 22-39 and IdempotencyKeyStoreIT.java lines 32-45. For DelayedQueueIT.pollDue_returnsPayload_onlyAfterDelay, wait up to a suitable timeout until pollDue returns the expected payload; apply the same condition-based waiting to the corresponding idempotency test, preserving the existing pre-delay assertions.src/main/java/com/piuda/callcare/global/config/redis/DelayedQueuePoller.java (1)
32-42: 🩺 Stability & Availability | 🔵 Trivial순차 처리로 인해 폴링 주기가 밀릴 수 있습니다.
handle()가 무거워지면 다음poll()실행이 지연될 수 있으니, 처리량이 늘어날 가능성이 있으면 비동기 처리나 전용 스레드풀 분리를 고려하세요.🤖 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 `@src/main/java/com/piuda/callcare/global/config/redis/DelayedQueuePoller.java` around lines 32 - 42, Update the poll method in DelayedQueuePoller so each due payload is processed asynchronously or delegated to a dedicated executor instead of blocking the scheduled polling thread on delayedJobHandler.handle. Preserve the existing per-payload exception logging and configure or reuse an appropriate bounded thread pool for processing.Source: Path instructions
🤖 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 `@src/main/java/com/piuda/callcare/global/config/redis/RedisConfig.java`:
- Around line 35-43: Remove the manual redisConnectionFactory and
stringRedisTemplate bean methods from RedisConfig so Spring Boot
RedisAutoConfiguration creates them and applies all spring.data.redis.*
properties. Preserve the existing `@Value` fields and redisConnectionHealthCheck
logic, updating imports or injection only as needed after removing these bean
definitions.
---
Nitpick comments:
In `@src/main/java/com/piuda/callcare/global/config/redis/DelayedQueue.java`:
- Around line 36-40: Update the RedisScript used by pollDue to avoid calling
unpack(due) with an unbounded public limit; either cap the accepted poll limit
to the Lua-safe range or replace the bulk ZREM with a loop that removes each due
item safely. Preserve polling and removal behavior for the default limit and
large requested limits.
In
`@src/main/java/com/piuda/callcare/global/config/redis/DelayedQueuePoller.java`:
- Around line 32-42: Update the poll method in DelayedQueuePoller so each due
payload is processed asynchronously or delegated to a dedicated executor instead
of blocking the scheduled polling thread on delayedJobHandler.handle. Preserve
the existing per-payload exception logging and configure or reuse an appropriate
bounded thread pool for processing.
In `@src/main/java/com/piuda/callcare/global/config/redis/RedisConfig.java`:
- Around line 49-58: Update the Redis connection configuration used by
LettuceConnectionFactory to apply a short command timeout, such as 2 seconds,
via LettuceClientConfiguration.builder().commandTimeout(...).build(), or switch
to the existing Spring Boot Redis auto-configuration with
spring.data.redis.timeout set accordingly. Ensure redisConnectionHealthCheck’s
connection.ping() cannot block application startup indefinitely.
In `@src/test/java/com/piuda/callcare/global/config/redis/DelayedQueueIT.java`:
- Around line 22-39: Replace fixed Thread.sleep(700) waits with Awaitility-based
condition polling in DelayedQueueIT.java lines 22-39 and
IdempotencyKeyStoreIT.java lines 32-45. For
DelayedQueueIT.pollDue_returnsPayload_onlyAfterDelay, wait up to a suitable
timeout until pollDue returns the expected payload; apply the same
condition-based waiting to the corresponding idempotency test, preserving the
existing pre-delay assertions.
🪄 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: b6d39e75-16d4-4a6a-a88b-36f0477251e7
📒 Files selected for processing (11)
build.gradlesrc/main/java/com/piuda/callcare/global/config/redis/DelayedJobHandler.javasrc/main/java/com/piuda/callcare/global/config/redis/DelayedQueue.javasrc/main/java/com/piuda/callcare/global/config/redis/DelayedQueuePoller.javasrc/main/java/com/piuda/callcare/global/config/redis/IdempotencyKeyStore.javasrc/main/java/com/piuda/callcare/global/config/redis/LoggingDelayedJobHandler.javasrc/main/java/com/piuda/callcare/global/config/redis/RedisConfig.javasrc/main/resources/application.ymlsrc/test/java/com/piuda/callcare/global/config/redis/AbstractRedisIntegrationTest.javasrc/test/java/com/piuda/callcare/global/config/redis/DelayedQueueIT.javasrc/test/java/com/piuda/callcare/global/config/redis/IdempotencyKeyStoreIT.java
Summary by CodeRabbit
새 기능
개선 사항