feat: add Idempotency-Key guard to prevent duplicate AI problem generation - #61
Conversation
…ation Multi-instance migration exposes duplicate AI-generation requests (double-click, network retry landing on a different instance) since there was no way to detect a resubmitted request. Use Redis SETNX with a 10min TTL, scoped per request, to reject retries while the original is still in flight. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 55 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 (1)
📝 WalkthroughWalkthroughAI 문제 생성 API가 필수 ChangesAI 문제 생성 멱등성
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller
participant Service
participant Redis
participant AI Generator
Client->>Controller: Idempotency-Key 및 AI 문제 생성 요청
Controller->>Service: idempotencyKey와 요청 데이터 전달
Service->>Redis: 10분 TTL 잠금 설정
Service->>AI Generator: 문제 생성 요청
AI Generator-->>Service: 생성된 문제 반환
Service->>Redis: 처리 실패 시 잠금 삭제
Service-->>Controller: 생성 결과 또는 중복 요청 오류
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 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: 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/domain/problem/service/ProblemServiceImpl.java`:
- Around line 306-335: Update the AI request locking flows in ProblemServiceImpl
(momogo-core/src/main/java/com/momogo/core/domain/problem/service/ProblemServiceImpl.java:306-335)
and RoomProblemServiceImpl
(momogo-core/src/main/java/com/momogo/core/domain/room/service/RoomProblemServiceImpl.java:135-164)
to generate a unique request token, store it as the lock value with the existing
TTL, and release the lock via Lua compare-and-delete so only the owner can
delete it. Also enforce or manage an AI-call timeout, retry, or cancellation
strategy so execution cannot silently outlive the fixed TTL and allow concurrent
generation.
🪄 Autofix
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: cfdf7912-60f4-4aaa-bdfe-f31bef70f6af
📒 Files selected for processing (8)
momogo-api/src/main/java/com/momogo/api/problem/ProblemController.javamomogo-api/src/main/java/com/momogo/api/room/RoomProblemController.javamomogo-core/src/main/java/com/momogo/core/domain/problem/exception/ProblemErrorCode.javamomogo-core/src/main/java/com/momogo/core/domain/problem/service/ProblemService.javamomogo-core/src/main/java/com/momogo/core/domain/problem/service/ProblemServiceImpl.javamomogo-core/src/main/java/com/momogo/core/domain/room/exception/RoomProblemErrorCode.javamomogo-core/src/main/java/com/momogo/core/domain/room/service/RoomProblemService.javamomogo-core/src/main/java/com/momogo/core/domain/room/service/RoomProblemServiceImpl.java
Backend now requires this header (see PR #61); without it the space AI-generation call fails with 400 MissingRequestHeaderException. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
idktomorrow
left a comment
There was a problem hiding this comment.
저는 별다른 문제점 찾을 수 없었습니다.
바쁜와중에도 작성하시느라 고생하셨습니다. ❤️
TTL 만료 후 다른 요청이 같은 키로 락을 재획득했을 때, 기존 요청의 실패 처리가 무조건 delete를 호출해 새 락을 지우는 문제가 있었음. 락 값을 요청별 토큰으로 바꾸고 Lua compare-and-delete로 소유자만 해제하도록 수정. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
catch(RuntimeException)만 처리해 성공 시 락이 TTL까지 남고, Error 계열(OOM 등) 발생 시 락 누수가 있었음. finally로 바꿔 성공/실패/Error 모든 경로에서 락이 해제되도록 수정. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
작업 내용
문제 생성 / AI 문제 생성 API에 Idempotency-Key 기반 중복 요청 차단 추가.
변경 사항
POST /api/spaces/{spaceId}/problems/ai,POST /api/rooms/{roomId}/problems/ai두 엔드포인트에 요청 식별자가 없어서 더블클릭/네트워크 재시도 시 AI API 중복 호출 및 문제 중복 저장이 가능한 상태였음.Idempotency-Key헤더(UUID)를 RedissetIfAbsent(TTL 10분)로 잠궈서, 같은 키로 들어온 재요청은409 CONFLICT(DUPLICATE_AI_REQUEST)로 차단.ProblemErrorCode,RoomProblemErrorCode에DUPLICATE_AI_REQUEST에러코드 추가 (기존GlobalExceptionHandler가ErrorCode.getHttpStatus()로 범용 매핑하므로 핸들러 수정은 불필요).체크리스트
참고 사항
Idempotency-Key헤더 미전송 시 모든 AI 생성 요청이 400으로 막힘 — 프론트 연동 별도 필요 (미착수).D:\project\문서\MoMoGo_문서\ai-problem-generation-idempotency-key.md관련 이슈
Summary by CodeRabbit
개선 사항
Idempotency-Key를 사용합니다.오류 처리