[Perf] 전체 인덱싱 Queue 적체 및 DB Pool Backpressure Benchmark 추가 - #142
Conversation
📝 WalkthroughWalkthroughWorker Queue와 Hikari Connection Pool backpressure 벤치마크를 추가했습니다. 실제 인프라에서 단계별 부하를 실행하고, Queue·Pool·처리량·정합성 지표를 수집합니다. 전용 Gradle 작업과 JSON·Markdown 결과 문서도 추가했습니다. ChangesWorker Queue Backpressure Benchmark
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Benchmark as WorkerQueueBackpressureBenchmark
participant MinIO
participant Worker
participant PostgreSQL
participant EmbeddingServer
participant Sampler as PoolQueueSampler
Benchmark->>MinIO: 프로파일 문서 업로드
MinIO->>Worker: Job 처리 시작
Worker->>PostgreSQL: Job 및 문서 상태 조회·저장
Worker->>EmbeddingServer: Embedding 생성
EmbeddingServer-->>Worker: 벡터 반환
Worker->>PostgreSQL: Chunk·Embedding 저장 및 INDEXED 전환
Sampler->>PostgreSQL: Queue·Pool 지표 샘플링
Sampler-->>Benchmark: 시계열 관측값 반환
Benchmark->>Benchmark: 프로파일 통계·압력 상태 집계
Possibly related PRs
🚥 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: 5
🧹 Nitpick comments (2)
src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureStatisticsTest.java (1)
61-85: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win검증 계약의 거부 경로 테스트를 보강하세요.
summarizeQueue는 빈 목록, null sample, 시각 역전을 거부합니다.parseProfiles는 rawValue가 null이거나 공백이면 defaults를 반환합니다. 현재 테스트는 두 경로를 모두 검증하지 않습니다. 이 계약은 실측 Sampler 입력을 방어하는 지점이므로 회귀 검증이 필요합니다.♻️ 제안 추가 테스트
`@Test` `@DisplayName`("Profile 입력이 없으면 기본 Profile을 사용한다") void fallsBackToDefaultProfiles() { List<LoadProfile> defaults = List.of(new LoadProfile(16, 4), new LoadProfile(32, 8)); assertThat(WorkerQueueBackpressureStatistics.parseProfiles(" ", defaults)) .containsExactlyElementsOf(defaults); } `@Test` `@DisplayName`("비어 있거나 시각이 역전된 Queue Sample을 거부한다") void rejectsInvalidQueueSamples() { assertThatThrownBy(() -> WorkerQueueBackpressureStatistics.summarizeQueue(List.of())) .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> WorkerQueueBackpressureStatistics.summarizeQueue(List.of( new QueueSample(2_000_000_000L, 1, 0, 0, 0), new QueueSample(1_000_000_000L, 1, 0, 0, 0) ))).isInstanceOf(IllegalArgumentException.class); }경로 지침의 "테스트 커버리지, 스프링 테스트 어노테이션, mock 사용법, 네이밍 규칙을 확인한다"에 따른 의견입니다.
🤖 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/opensource/docgrid/e2e/WorkerQueueBackpressureStatisticsTest.java` around lines 61 - 85, 보호해야 할 입력 검증 계약에 대한 테스트가 누락되어 있습니다. WorkerQueueBackpressureStatisticsTest에 parseProfiles의 null 또는 공백 rawValue가 기본 Profile 목록을 반환하는지 검증하는 테스트를 추가하고, summarizeQueue가 빈 목록과 시간이 역전된 QueueSample 목록에 IllegalArgumentException을 발생시키는지 각각 검증하세요.Source: Path instructions
src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureBenchmark.java (1)
436-445: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win업로드 대기 초과가 결과 보존 의도와 어긋납니다.
436행 주석은 성공과 실패를 모두 결과로 보존한다고 선언합니다. 그러나
future.get(PROFILE_TIMEOUT_SECONDS, TimeUnit.SECONDS)가TimeoutException을 던지면 예외가 그대로 전파되어 해당 run은ProfileRun으로 기록되지 않습니다. 대기 시간도 future 단위로 누적되어 총 대기가 제한 시간을 넘을 수 있습니다. 대기 초과를 업로드 실패로 변환하면 붕괴 판정(COLLAPSED) 경로로 기록됩니다.♻️ 제안 수정
List<UploadAttempt> attempts = new ArrayList<>(profile.documentCount()); + long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(PROFILE_TIMEOUT_SECONDS); for (Future<UploadAttempt> future : futures) { - attempts.add(future.get(PROFILE_TIMEOUT_SECONDS, TimeUnit.SECONDS)); + long remainingNanos = Math.max(0L, deadline - System.nanoTime()); + try { + attempts.add(future.get(remainingNanos, TimeUnit.NANOSECONDS)); + } catch (TimeoutException exception) { + future.cancel(true); + attempts.add(UploadAttempt.failure( + millis(remainingNanos), + exception.getClass().getSimpleName() + )); + } }🤖 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/opensource/docgrid/e2e/WorkerQueueBackpressureBenchmark.java` around lines 436 - 445, Update the future-collection loop in the benchmark’s upload-result flow to catch per-future TimeoutException and convert it into an UploadAttempt failure result, preserving the run for COLLAPSED evaluation instead of propagating the exception. Avoid applying the full profile timeout independently to every future; enforce the intended overall wait budget while still collecting all completed results. Keep uploader shutdown and termination handling unchanged.
🤖 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 `@docs/design/gimin-`#141-worker-queue-backpressure-benchmark.md:
- Line 37: Update the server-tuning bullet in the benchmark document to replace
the nonexistent “OpenSQL” component with the actual PostgreSQL, MinIO, and
BGE-M3 components referenced elsewhere, preserving the intended exclusion scope.
In `@docs/test-results/gimin-`#141-worker-queue-backpressure-benchmark.md:
- Around line 39-64: 문서의 자동화 실행 결과에 Swagger UI 수동 검증 항목을 추가하세요. 실제로 실행하지 않았다면
결과를 추측하지 말고 상태를 “미실행”으로 기록하며 사유를 명시하세요. 또한 자동화 전용 보고서를 이 경로에 둘 수 있는지 관련 예외를
확인하고, 해당 문서 형식에 맞게 결과를 정리하세요.
- Line 5: 측정일 항목의 2026-08-11 값을 벤치마크가 실제로 실행된 날짜로 수정하세요. 실행일이 2026-08-11 이후라면
벤치마크를 실행한 뒤 문서를 갱신하고, 그렇지 않다면 실제 실행일을 기록하세요.
In
`@src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureBenchmark.java`:
- Line 224: WorkerQueueBackpressureBenchmark 클래스의 `@Timeout` 값을 기본 부하 예산인 최대 8회 실행
× PROFILE_TIMEOUT_SECONDS 600초와 예열·정합성 질의 시간을 모두 포함하도록 3,600초보다 크게 조정하세요.
In
`@src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureStatistics.java`:
- Around line 79-83: Update the average queue-depth calculation in
WorkerQueueBackpressureStatistics to derive elapsedSeconds from the difference
between the final and first validated sample elapsedNanos values, matching the
integration interval used by queueDepthAucDocumentSeconds. Preserve the existing
zero-duration fallback to the first sample’s queue depth.
---
Nitpick comments:
In
`@src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureBenchmark.java`:
- Around line 436-445: Update the future-collection loop in the benchmark’s
upload-result flow to catch per-future TimeoutException and convert it into an
UploadAttempt failure result, preserving the run for COLLAPSED evaluation
instead of propagating the exception. Avoid applying the full profile timeout
independently to every future; enforce the intended overall wait budget while
still collecting all completed results. Keep uploader shutdown and termination
handling unchanged.
In
`@src/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureStatisticsTest.java`:
- Around line 61-85: 보호해야 할 입력 검증 계약에 대한 테스트가 누락되어 있습니다.
WorkerQueueBackpressureStatisticsTest에 parseProfiles의 null 또는 공백 rawValue가 기본
Profile 목록을 반환하는지 검증하는 테스트를 추가하고, summarizeQueue가 빈 목록과 시간이 역전된 QueueSample 목록에
IllegalArgumentException을 발생시키는지 각각 검증하세요.
🪄 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: 0fce8449-6dab-4963-8992-bf70e7e42241
📒 Files selected for processing (6)
build.gradledocs/design/gimin-#141-worker-queue-backpressure-benchmark.mddocs/test-results/gimin-#141-worker-queue-backpressure-benchmark.mdsrc/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureBenchmark.javasrc/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureStatistics.javasrc/test/java/com/opensource/docgrid/e2e/WorkerQueueBackpressureStatisticsTest.java
|
|
||
| - 관련 이슈: [#141](https://github.com/DocGrid/backend/issues/141) | ||
| - 설계: [Worker Queue 적체·DB Pool Backpressure Benchmark 설계](../design/gimin-%23141-worker-queue-backpressure-benchmark.md) | ||
| - 측정일: 2026-08-11 |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
측정일을 실제 실행일로 수정하세요.
현재 검토 기준일은 2026년 8월 10일입니다. Line 5는 측정일을 2026-08-11로 기록합니다. 실제 실행일이 2026년 8월 11일 이후라면 실행 후 문서를 갱신하세요. 그렇지 않다면 실제 실행일로 수정하세요.
🤖 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 `@docs/test-results/gimin-`#141-worker-queue-backpressure-benchmark.md at line
5, 측정일 항목의 2026-08-11 값을 벤치마크가 실제로 실행된 날짜로 수정하세요. 실행일이 2026-08-11 이후라면 벤치마크를 실행한
뒤 문서를 갱신하고, 그렇지 않다면 실제 실행일을 기록하세요.
🔍️ 작업 내용
✨ 상세 설명
workerQueueBackpressureTestGradle task 추가실측 결과
✅ 검증
./gradlew test --tests com.opensource.docgrid.e2e.WorkerQueueBackpressureStatisticsTestDB_SSLMODE=disable ./gradlew workerQueueBackpressureTest—BUILD SUCCESSFUL in 3m 29sDB_SSLMODE=disable JWT_SECRET=<test-only-value> ./gradlew test—BUILD SUCCESSFUL in 25sgit diff --check로컬 Docker PostgreSQL은 SSL을 제공하지 않아 성공 실행에만
DB_SSLMODE=disable을 명시했으며 저장소 설정과 시크릿은 변경하지 않았습니다.🛠️ 추후 리팩토링 및 고도화 계획
💬 리뷰 요구사항
Summary by CodeRabbit