[REFAC#389] fetcher/worker/retry_scheduler → publisher.RetryScheduler 이동 - #399
Conversation
… (이슈 #389) 메타 #385 Sub 4 — Kafka I/O 책임을 publisher 단일 facade 로 통합하는 흐름의 일부. 이동: - internal/processor/fetcher/worker/retry_scheduler.go → internal/publisher/retry.go - test/.../worker/retry_scheduler_test.go → test/internal/publisher/retry_test.go - pool.SetRetryScheduler 통합 시나리오는 worker_test 에 별도 파일로 분리 (test/.../worker/pool_retry_scheduler_test.go) 인터페이스 정의는 publisher 측 (이슈 #396 원칙 — Kafka I/O 단일 책임): - RetryScheduler / RetrySchedulerHolder (S 필드 export 으로 atomic.Pointer 호환) - KafkaImmediateRetryScheduler / NewKafkaImmediateRetryScheduler - RedisDelayedRetryScheduler / NewRedisDelayedRetryScheduler / RedisRetrySchedulerConfig - DefaultRedisRetrySchedulerConfig - retryQueueClient (internal) worker.pool 변경: - atomic.Pointer[publisher.RetrySchedulerHolder] 로 타입 갱신 - resolveRetryScheduler → publisher.NewKafkaImmediateRetryScheduler fallback - crawlTopic 은 publisher 측 helper 재사용 (worker 의 topicForPriority 는 유지 — requeue 로그 용) cmd/issuetracker/main.go wiring: - crawlerWorker.RetryScheduler → publisher.RetryScheduler - crawlerWorker.NewRedisDelayedRetryScheduler → publisher.NewRedisDelayedRetryScheduler - crawlerWorker.DefaultRedisRetrySchedulerConfig → publisher.DefaultRedisRetrySchedulerConfig Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThe PR moves retry scheduler types and implementations from the worker package to the publisher package. Worker components (manager and pool) update their imports and type signatures to use ChangesRetry Scheduler Consolidation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Code Review
This pull request refactors the RetryScheduler logic by moving it from the worker package to a new publisher package to adhere to the 'Kafka I/O single responsibility principle.' This involves updating type references across main.go, manager.go, and pool.go, as well as migrating and updating associated tests. Feedback includes improving the naming of the RetrySchedulerHolder field for better readability, centralizing topic mapping logic to avoid duplication, and cleaning up unused variables or restoring helpful comments in the test suite.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
test/internal/processor/fetcher/worker/pool_retry_scheduler_test.go (1)
56-56: ⚡ Quick winRemove unused global counter.
The
poolRetrySchedulerCounteris declared but never meaningfully used. Line 91 just loads it to silence the linter, which is a code smell.Options:
- If not needed, remove both the declaration and line 91
- If needed for future tests, add a TODO comment explaining the intent
🤖 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 `@test/internal/processor/fetcher/worker/pool_retry_scheduler_test.go` at line 56, Remove the unused global atomic counter by deleting the declaration poolRetrySchedulerCounter and the only usage that calls poolRetrySchedulerCounter.Load() (the linter-silencing read); if you intend to keep it for future tests instead, add a clear TODO comment above poolRetrySchedulerCounter explaining its intended purpose and why it is currently unused so the linter-warning won't be silenced implicitly.
🤖 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 `@internal/publisher/retry.go`:
- Line 73: The duplicate utility function crawlTopic is defined in both
internal/scheduler/throttle.go and internal/publisher/publisher.go; remove the
duplicate in publisher.go and consolidate a single crawlTopic implementation in
a shared location (e.g., keep it in internal/scheduler/throttle.go or create
internal/scheduler/priority.go), then update the publisher package to import and
call that shared crawlTopic function instead of its local copy; ensure the
consolidated function has the same signature and update imports and any package
references in publisher.go (e.g., calls in retry.go/publisher.go) so compilation
and behavior remain unchanged.
---
Nitpick comments:
In `@test/internal/processor/fetcher/worker/pool_retry_scheduler_test.go`:
- Line 56: Remove the unused global atomic counter by deleting the declaration
poolRetrySchedulerCounter and the only usage that calls
poolRetrySchedulerCounter.Load() (the linter-silencing read); if you intend to
keep it for future tests instead, add a clear TODO comment above
poolRetrySchedulerCounter explaining its intended purpose and why it is
currently unused so the linter-warning won't be silenced implicitly.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4df792bb-13ea-4711-b935-b0e0ef4cb7cb
📒 Files selected for processing (6)
cmd/issuetracker/main.gointernal/processor/fetcher/worker/manager.gointernal/processor/fetcher/worker/pool.gointernal/publisher/retry.gotest/internal/processor/fetcher/worker/pool_retry_scheduler_test.gotest/internal/publisher/retry_test.go
There was a problem hiding this comment.
Pull request overview
fetcher/worker에 있던 RetryScheduler(즉시 Kafka 재발행 + Redis 지연 재시도)를 internal/publisher로 이동해, Kafka publish 책임을 publisher 패키지로 단일화하려는 리팩토링입니다(메타 #385의 “Kafka I/O 단일 책임” 방향에 맞춘 정리).
Changes:
internal/publisher/retry.go로 RetryScheduler 인터페이스/구현체 및 Redis delayed retry 로직을 이동- fetcher worker pool/manager가
publisher.RetryScheduler를 주입/해결하도록 타입 및 wiring 갱신 - main wiring 및 테스트를 신규 위치로 이동하고, pool 통합 시나리오 테스트를 worker_test에 분리 추가
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
internal/publisher/retry.go |
RetryScheduler 인터페이스/구현체 및 Redis delayed retry 로직을 publisher로 이동, drain timeout 명시화 |
internal/processor/fetcher/worker/pool.go |
retry scheduler holder를 publisher.RetrySchedulerHolder로 변경하고 fallback 생성 경로를 publisher로 연결 |
internal/processor/fetcher/worker/manager.go |
ManagerConfig.RetryScheduler 타입을 publisher.RetryScheduler로 변경하여 주입 경로 일원화 |
cmd/issuetracker/main.go |
RetryScheduler wiring을 worker → publisher 생성자로 전환 |
test/internal/publisher/retry_test.go |
RetryScheduler 단위 테스트를 publisher_test로 이동하고 producer mock 충돌을 피하도록 정리 |
test/internal/processor/fetcher/worker/pool_retry_scheduler_test.go |
pool.SetRetryScheduler 통합(인라인 publish 우회) 시나리오 테스트를 별도 파일로 분리 추가 |
Comments suppressed due to low confidence (1)
internal/publisher/retry.go:29
- RetrySchedulerHolder의 필드가 S로 export되어 있어, 외부 패키지가 holder 포인터를 보관한 뒤 S를 직접 변경할 수 있습니다. 이렇게 되면 atomic.Pointer로 교체한다는 의도와 달리 non-atomic 경로로 값이 바뀌거나(data race 위험) API가 불필요하게 노출될 수 있습니다. publisher 패키지에 holder 생성자(예: NewRetrySchedulerHolder) 또는 Set 메서드를 제공하고, 필드는 unexported로 유지하는 형태를 고려해 주세요.
…er.CrawlTopic 통합 + 불필요 counter 제거 gemini + coderabbit + Copilot 리뷰 반영: 1. RetrySchedulerHolder 필드 rename — `S` → `Scheduler` - atomic.Pointer 호환을 위해 노출하되 명확한 이름으로 가독성 개선 (gemini #1, #3, #4) - publisher/retry.go 정의 + pool.go SetRetryScheduler / resolveRetryScheduler 의 참조 갱신 2. CrawlTopic 단일화 (gemini #2 + coderabbit) - publisher 의 `crawlTopic` (unexported) → `CrawlTopic` (exported) 로 노출 - worker 의 `topicForPriority` 제거 — pool.requeueWithRetry / manager.Publish 가 publisher.CrawlTopic 직접 호출 - scheduler/throttle.go 의 중복 `crawlTopic` 제거 — publisher.CrawlTopic 사용 - Kafka I/O 책임이 publisher 단일 출처라는 메타 #385 원칙과 일관 3. pool_retry_scheduler_test.go 의 불필요 counter 제거 (Copilot) - poolRetrySchedulerCounter atomic.Int32 + sync/atomic import 삭제 - 테스트 검증 로직과 무관한 placeholder 였음 4. fakeRetryQueue 의 `// ScheduledAt 정렬 유지` 주석 복원 (gemini #7) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
연관 이슈
Closes #389
부모 메타: #385 — Publisher 통합 Sub 4
구현 내용
internal/processor/fetcher/worker/retry_scheduler.go의 RetryScheduler 인프라를internal/publisher/retry.go로 통째로 이동. Kafka I/O 단일 책임 원칙 (이슈 #396) 에 따라 인터페이스도 publisher 측에서 정의.이동 내역
worker.RetrySchedulerinterfacepublisher.RetrySchedulerworker.retrySchedulerHolder(unexported)publisher.RetrySchedulerHolder(exportedS필드 — atomic.Pointer 호환)worker.KafkaImmediateRetryScheduler+NewKafkaImmediateRetrySchedulerpublisher.*worker.RedisDelayedRetryScheduler+NewRedisDelayedRetrySchedulerpublisher.*worker.RedisRetrySchedulerConfig+DefaultRedisRetrySchedulerConfigpublisher.*worker.retryQueueClient(unexported)publisher.retryQueueClientworker.drainTimeout(재시도용 5s)publisher.retryDrainTimeout(이름만 명시화)worker.pool / manager 변경
atomic.Pointer[retrySchedulerHolder]→atomic.Pointer[publisher.RetrySchedulerHolder]SetRetryScheduler(rs RetryScheduler)→SetRetryScheduler(rs publisher.RetryScheduler)resolveRetryScheduler()의 fallback →publisher.NewKafkaImmediateRetryScheduler(p.producer)ManagerConfig.RetryScheduler필드 타입 →publisher.RetrySchedulertopicForPriority/drainTimeout은 유지 (requeueWithRetry 로그 + 다른 sendToDLQ/commit 경로에서 사용)cmd/issuetracker/main.go wiring
var retryScheduler crawlerWorker.RetryScheduler→publisher.RetrySchedulercrawlerWorker.NewRedisDelayedRetryScheduler(...)→publisher.NewRedisDelayedRetryScheduler(...)crawlerWorker.DefaultRedisRetrySchedulerConfig()→publisher.DefaultRedisRetrySchedulerConfig()테스트
test/internal/processor/fetcher/worker/retry_scheduler_test.go전체 →test/internal/publisher/retry_test.go이동 (packagepublisher_test로 재선언,worker.X→publisher.X일괄 치환, mock producer 이름은retryMockProducer로 prefix 변경하여 다른 publisher_test 파일과 충돌 회피)TestKafkaConsumerPool_SetRetryScheduler_BypassesInlinePublish만 worker_test 측 신규 파일pool_retry_scheduler_test.go로 분리 — pool 의 mockConsumer/mockProducer/marshaledJobMsg/runPool 등 worker_test 헬퍼를 그대로 활용하면서 publisher.NewRedisDelayedRetryScheduler 로 injectCI / 머지 게이트 점검
gofmt -l— cleango build ./internal/... ./cmd/... ./pkg/...— passgo test -race -count=1 ./test/...— 전 패키지 통과 (publisher 1.41s / worker 1.22s 포함)[REFAC#389]정규식 매칭[REFAC]:prefix + 한국어변경 영향 범위 + 위험도
RetrySchedulerHolder.S필드를 export 한 이유: atomic.Pointer 가 외부 패키지의 unexported 필드를 직접 다룰 수 없음. holder 자체가 wrapper 이므로 노출 영향 미미.롤백 계획
crawlerWorker로 되돌아감.후속
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes