[Feat] PENDING Job Claim 및 Lease Lock 구현 - #49
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (24)
📝 WalkthroughWalkthroughChanges이번 변경은 Embedding Job Claim
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Admin
participant Controller
participant ClaimService
participant PostgreSQL
participant EventRepository
Admin->>Controller: POST claim(workerId)
Controller->>ClaimService: claim(workerId)
ClaimService->>PostgreSQL: validate worker and select PENDING with SKIP LOCKED
PostgreSQL-->>ClaimService: locked job
ClaimService->>PostgreSQL: update PROCESSING, worker, token, lease
ClaimService->>EventRepository: save LOCKED event
EventRepository->>PostgreSQL: persist event
ClaimService-->>Controller: ClaimedEmbeddingJobResponse
Controller-->>Admin: 200 or 204
Possibly related PRs
Suggested labels: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8)src/main/resources/application-test.ymlTraceback (most recent call last): src/main/resources/application.ymlTraceback (most recent call last): 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 |
목적
등록된 인덱싱 Worker가 PENDING Embedding Job 하나를 중복 없이 Claim하고, DB Transaction이 끝난 뒤에도 현재 소유권을 확인할 수 있도록 Lease와 Claim Token을 발급합니다.
이 PR은 Job을 실제로 파싱·청킹·임베딩하는 실행 단계가 아니라, 후속 실행을 시작하기 전에 필요한 작업 소유권 획득 단계를 구현합니다.
Closes #47
구현 범위
POST /admin/indexing-jobs/claim?workerId={workerId}관리자 APIpriority DESCcreated_at ASCid ASCFOR UPDATE SKIP LOCKED기반 동시 Claim 제어PROCESSING상태 전이locked_atlock_expires_atclaim_tokenLOCKED인덱싱 이벤트 저장claim_token컬럼 추가동작 흐름
Worker 검증 실패 시에는 Queue 행 잠금을 시도하지 않습니다. Claim 도중 예외가 발생하면 Job 변경과 이벤트 저장이 함께 Rollback되고, 획득한 DB 행 잠금도 Transaction 종료와 함께 해제됩니다.
동시성 설계
lock_expires_at)일반
FOR UPDATE는 최우선 Job의 잠금이 풀릴 때까지 뒤 Worker를 대기시켜 Queue 전체 처리량을 떨어뜨릴 수 있습니다.SKIP LOCKED는 이미 경쟁 중인 행을 기다리지 않고 다음 후보를 선택하므로 여러 Worker가 서로 다른 Job을 병렬로 Claim할 수 있습니다.DB 행 잠금은 파싱·청킹·임베딩 전체 시간 동안 유지하지 않습니다. 외부 처리 시간을 DB Transaction에 포함하면 Connection과 행 잠금을 장시간 점유하므로, 이 PR에서는 소유권 기록 직후 Commit하고 실제 인덱싱은 후속 작업에서 수행하도록 경계를 나눴습니다.
응답 및 오류
200 OK204 No Content404 WORKER-001409 WORKER-002/admin/**기존 정책에 따라 ADMIN 이외 요청:403 Forbidden응답에는 Entity를 직접 노출하지 않고 Job, Worker, 문서 버전, Embedding Model 식별자와 Token·Lease 정보만 담습니다.
설계 문서와 코드 주석
@Transactional, JPA Managed Entity, Dirty Checking 내부 동작READ COMMITTED와SKIP LOCKED동작SKIP LOCKED선택 이유변경된 클래스에는 역할과 책임 경계를 설명하는 클래스 주석을 추가했습니다. Claim처럼 순서가 중요한 흐름에는
1.,2.,3.,4.주석을 사용했고, 핵심 줄에는 문법 설명이 아니라 불변식과 선택 이유가 드러나도록 보강했습니다. 이 규칙은AGENTS.md에도 기록했습니다.테스트
./gradlew clean build— 192 tests 통과./gradlew compileTestJava통과IndexingJobAdminControllerTestEmbeddingJobConverterTestEmbeddingJobTestEmbeddingJobClaimServiceTestIndexingWorkerPropertiesTestLOCKED이벤트의 단일 소유자 Commit후속 범위
다음 항목은 이 PR에 포함하지 않습니다.
Summary by CodeRabbit
새로운 기능
204 No Content를 반환합니다.안정성 개선
문서화