fix: 썸네일 큐 초과 시 성공한 업로드가 500으로 응답되는 문제 수정 - #108
Merged
Conversation
thumbnailExecutor 큐가 가득 차면 afterCommit() 콜백에서 던진 RejectedExecutionException이 그대로 전파돼, 사진은 이미 커밋됐는데 응답만 500으로 깨지는 상태 불일치가 있었다. 예외를 잡아 로그만 남기고 PENDING 상태로 두면 PhotoSweepScheduler가 재수거하도록 수정. PhotoSweepScheduler.resubmitStaleThumbnailJobs()도 같은 예외에 보호되어 있지 않아, 큐가 지속적으로 가득 찬 상황에서는 스윕 배치의 첫 사진에서 루프가 중단되고 나머지 사진들이 그 사이클에서 조용히 누락되는 동일한 결함이 있었다. 같은 방식으로 사진 단위 try/catch를 추가해 한 사진의 실패가 나머지 재제출을 막지 않도록 수정. Closes #86
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
#86은 꽤 예전에 등록된 이슈라 현재도 유효한지 먼저 검증했고, 최근 변경들(썸네일 READY 정합성 수정 등)과는 무관하게 버그가 그대로 남아있는 걸 확인했습니다.
버그 상황: 업로드 완료 등록(
PhotoUploadService.completeUpload())이 사진을 DB에 커밋한 직후,afterCommit()콜백에서 각 사진의 썸네일 생성 작업을thumbnailExecutor(ThreadPoolTaskExecutor, core=4/max=6/queue=100)에 제출합니다. 큐가 가득 차면RejectedExecutionException이 나는데, 이 시점엔 이미 사진이 정상 커밋된 뒤라 예외가 그대로 전파되면 업로드는 성공했는데 응답만 500으로 깨지는 상태 불일치가 생깁니다. 같은 모임에서 여러 명이 몰아서 업로드하는 패턴이 자연스러운 서비스 특성상, 동시 사용자 5~6명만 겹쳐도 흔히 발생할 수 있는 상황이었습니다(이슈 원본의 벤치마크: 동시 사용자 3명만으로도 큐 56/100까지 참).리뷰 과정에서 같은 결함이 복구 경로인
PhotoSweepScheduler.resubmitStaleThumbnailJobs()(5분마다 도는 재수거 스윕)에도 그대로 있는 걸 추가로 발견했습니다. 이 스케줄러는 원래 "큐 제출이 실패해도 사진은 PENDING으로 남아있으니 나중에 재수거된다"는 안전망 역할인데, 정작 그 스윕 자체가 같은 예외에 무방비해서, 큐가 지속적으로 가득 찬 상황에서는 스윕 배치의 첫 사진에서 루프가 중단되고 나머지 사진들이 그 사이클에서 조용히 누락됐습니다.What changed / What improved
PhotoUploadService:thumbnailProcessingService.process()호출을 try/catch로 감싸RejectedExecutionException(Spring의TaskRejectedException포함)을 로그만 남기고 삼키도록 수정.PENDING으로 남고, 스윕이 나중에 재수거해 썸네일을 생성. 배치 업로드(최대 20장) 중 한 장이 거부돼도 나머지 장은 계속 정상 제출됨(이전엔 첫 장에서 예외가 나면 루프 자체가 중단돼 나머지도 제출 시도조차 못 했음).PhotoSweepScheduler: 같은 예외를 사진 단위 try/catch로 처리하도록 수정(같은 클래스의 다른 두 메서드가 이미 쓰던 패턴과 통일).docs/architecture/backend-architecture.md4.3절에 큐 초과 시 안전 처리 방식을 결정 기록으로 추가.부하 재측정과
thumbnail.executor.queue-capacity값 확정은 실측이 필요한 별도 작업이라 #107로 분리했습니다.Test plan
PhotoUploadServiceTest— 큐 초과 시afterCommit()콜백이 예외를 전파하지 않음을 검증PhotoSweepSchedulerTest— 한 사진이 큐 초과로 실패해도 나머지 사진은 계속 재제출됨을 검증SharedAlbumPhotoUploadLimitIntegrationTest— 실제 Postgres + MockMvc로 큐 초과 상황에서도 완료등록 API가 201을 반환함을 확인develop과 병합 충돌 없음Closes #86
🤖 Generated with Claude Code