Skip to content

[REFAC#391] PriorityResolver chain → publisher 측 이동 + 모든 PublishX 통과 - #409

Merged
juhy0987 merged 3 commits into
mainfrom
refactor/#391/publisher-resolver
May 13, 2026
Merged

juhy0987 merged 3 commits into
mainfrom
refactor/#391/publisher-resolver

Conversation

@juhy0987

@juhy0987 juhy0987 commented May 13, 2026

Copy link
Copy Markdown
Member

연관 이슈

Closes #391
부모 메타: #385 — Publisher 통합 Sub 6 (마지막)

본 sub 머지로 메타 #385 (Publisher 통합) 완료.

구현 내용

1. resolver.go 위치 이동

internal/processor/fetcher/worker/resolver.go
  → internal/publisher/resolver.go
  • 패키지 선언만 변경, 인터페이스 / 구현 로직 동일
  • ChainablePriorityResolver / ExplicitPriorityResolver / SourcePriorityResolver / RuleBasedPriorityResolver / DefaultPriorityResolver / CompositeResolver 모두 이동
  • PriorityResolver 인터페이스는 publisher.go 에 이미 정의 — 중복 제거

2. 모든 PublishX 가 resolver chain 통과

publisher.buildMessagep.resolver.Resolve(job) 를 호출하도록 변경 — 단일 진입점.

PublishX 경로
PublishChained (chain.go) buildMessage 경유 → resolver 통과
PublishSeed (seed.go) buildMessage 경유 → resolver 통과
PublishJob (publisher.go) buildMessage 경유 → resolver 통과
KafkaImmediateRetryScheduler.Enqueue (retry.go) buildMessage 경유 → resolver 통과
RedisDelayedRetryScheduler.republish (retry.go) buildMessage 경유 → resolver 통과

chain.go 의 명시적 job.Priority = p.resolver.Resolve(job) 호출 제거 (이중 평가 회피).

3. ExplicitPriorityResolver 를 chain 1순위 로

-resolver := crawlerWorker.NewCompositeResolver(core.PriorityNormal)
-resolver.Add(crawlerWorker.NewSourcePriorityResolver(core.PriorityNormal))
-resolver.Add(crawlerWorker.NewRuleBasedPriorityResolver(core.PriorityNormal))
+resolver := publisher.NewCompositeResolver(core.PriorityNormal)
+resolver.Add(&publisher.ExplicitPriorityResolver{})       // 1순위: 명시 priority 보존
+resolver.Add(publisher.NewSourcePriorityResolver(core.PriorityNormal))
+resolver.Add(publisher.NewRuleBasedPriorityResolver(core.PriorityNormal))

발행자가 job.Priority 를 사전 명시한 경우 (scheduler seed entry / worker retry / fetcher upgrader 등) 그 값이 보존됨 — ExplicitPriorityResolver.CanResolve 가 true 반환.

4. fetcher/worker.PoolManager 정리

  • PriorityResolver 필드 타입 → publisher.PriorityResolver (구 worker.PriorityResolver 정의 제거)
  • Publish()job.Priority = priority 갱신 제거 — publisher 가 buildMessage 안에서 처리. resolver 가 stateless · idempotent 라 manager 의 로깅용 평가는 안전.

CI / 머지 게이트 점검

  • gofmt -l internal/ cmd/ test/ examples/ — clean
  • go build ./internal/... ./cmd/... ./test/... ./examples/... — pass
  • go test -race -count=1 -timeout=180s ./test/... — 전 패키지 통과
  • PR 타이틀 [REFAC#391]
  • commit [REFAC]: prefix + 한국어

변경 영향 범위 + 위험도

  • 영향: publisher / fetcher worker manager / main.go wiring (5 파일, 5 changes)
  • 위험도 Low:
    • resolver 로직 자체 무변경 — 패키지 이동 + import path 변경
    • ExplicitPriorityResolver 추가로 발행자 명시 priority 가 보존됨 — 이전 동작 (Source/Rule 만 평가) 에서 explicit 가 누락되던 잠재 회귀 도리어 보강
    • 모든 기존 테스트 통과

메타 #385 완료

본 sub 머지 후 메타 #385 (Publisher 통합) 의 6 sub 모두 완료:

Sub 이슈 PR 상태
1 #386 #394/#395 머지
2 #387 #397 머지
3 #388 #398 머지
4 #389 #399 머지
5 #390 #400 머지
6 #391 본 PR 머지 시 메타 close
7 #392 #401 머지
8 #393 #408 머지

본 PR 머지 시 메타 #385 도 함께 close.

롤백 계획

PR revert 시 resolver 파일이 worker 측으로 다시 이동 + main.go wiring 원복 — 5 파일 동시 원복으로 회귀 없음.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed priority handling during message publishing to correctly preserve explicitly set job priorities instead of overriding them with default values.
  • Chores

    • Refactored internal priority resolution system for improved consistency and maintainability across publish operations.

Review Change Stack

…391)

메타 #385 Sub 6 (마지막) — fetcher/worker 의 PriorityResolver chain 을 publisher 측으로
이동하고, 모든 PublishX 메소드가 buildMessage 를 통해 resolver chain 을 일관 통과하도록 통합.

## 이동

- internal/processor/fetcher/worker/resolver.go → internal/publisher/resolver.go
- 패키지 선언만 변경, 인터페이스 / 구현 로직 동일 (ExplicitPriorityResolver,
  SourcePriorityResolver, RuleBasedPriorityResolver, DefaultPriorityResolver,
  CompositeResolver, ChainablePriorityResolver)
- PriorityResolver 인터페이스는 publisher.go 에서 이미 정의 — 중복 제거

## 모든 PublishX 통과

- publisher.buildMessage 가 p.resolver.Resolve(job) 를 호출하도록 변경 — 단일 진입점
- PublishChained / PublishSeed / PublishJob / KafkaImmediateRetryScheduler.Enqueue /
  RedisDelayedRetryScheduler.republish 모두 buildMessage 경유 → 자동으로 resolver 통과
- chain.go 의 명시적 resolver.Resolve(job) 호출 제거 (이중 평가 회피)

## 명시 priority 보존

- main.go wiring 에 ExplicitPriorityResolver 를 chain 1순위 로 추가
- 발행자 (scheduler seed entry / worker retry / fetcher upgrader 등) 가 job.Priority 를
  사전 명시한 경우 그 값이 보존됨 — ExplicitPriorityResolver.CanResolve 가 true 반환
- 후속 Source/Rule 기반 resolver 는 explicit 미설정 시에만 적용

## fetcher/worker.PoolManager

- PriorityResolver 필드 타입 → publisher.PriorityResolver (구 worker.PriorityResolver 정의 제거)
- Publish() 의 명시 priority 갱신 (job.Priority = priority) 제거 — publisher 가 buildMessage
  안에서 처리. resolver 가 stateless · idempotent 라 manager 의 로깅용 평가는 안전

## 검증

- go build ./internal/... ./cmd/... ./test/... ./examples/... — pass
- go test -race -count=1 -timeout=180s ./test/... — 전 패키지 통과
- gofmt clean

본 sub 머지로 메타 #385 (Publisher 통합) 완료.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 04:28
@juhy0987 juhy0987 added the refactor Code refactoring label May 13, 2026
@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@juhy0987 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 50 minutes and 20 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0897abb8-02e9-4ea8-851b-400378be776a

📥 Commits

Reviewing files that changed from the base of the PR and between 270cfe0 and 0bbd3bb.

📒 Files selected for processing (2)
  • internal/processor/fetcher/worker/manager.go
  • internal/publisher/publisher.go
📝 Walkthrough

Walkthrough

The PR moves crawler job priority resolution logic from the worker package into the publisher package, implementing a chain-of-responsibility resolver pattern. All PublishX methods now route through a unified resolver chain instantiated in main(), with explicit priorities preserved when set and fallback resolution applied consistently across seed, chained, retry, and upgrade flows.

Changes

Priority Resolver Chain Migration to Publisher

Layer / File(s) Summary
Publisher resolver chain contract and implementations
internal/publisher/resolver.go
Defines ChainablePriorityResolver interface and exports ExplicitPriorityResolver, SourcePriorityResolver, RuleBasedPriorityResolver, DefaultPriorityResolver, and CompositeResolver types using chain-of-responsibility pattern for ordered priority resolution.
Publisher buildMessage integration with resolver
internal/publisher/publisher.go, internal/publisher/chain.go
Expanded PriorityResolver documentation; buildMessage now applies p.resolver.Resolve(job) to set job.Priority before marshaling. buildJobMessages delegates resolver handling to buildMessage for consistency across all publish paths.
PoolManager type update and behavior refactoring
internal/processor/fetcher/worker/manager.go
PoolManager field and NewPoolManager parameter type changed to publisher.PriorityResolver; Publish now resolves priority for logging only without mutating job.Priority in-place.
Main application resolver chain instantiation
cmd/issuetracker/main.go
Instantiates CompositeResolver with ExplicitPriorityResolver first (preserving explicit priorities), followed by SourcePriorityResolver and RuleBasedPriorityResolver, with DefaultPriorityResolver as terminal fallback.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • EinSofINTEREST/IssueTracker#391: The PR directly implements the parent issue's refactoring objectives to move the resolver chain to the publisher layer and ensure all PublishX methods pass through the unified chain.
  • EinSofINTEREST/IssueTracker#385: The PR completes Sub 6 of this meta-issue by centralizing the resolver chain in the publisher package as the single source for priority routing.

Possibly related PRs

  • EinSofINTEREST/IssueTracker#400: Both PRs update internal/processor/fetcher/worker/manager.go and integrate PoolManager with the publisher layer's resolver types and behavior.

Suggested labels

refactor

Poem

🐰 The resolvers now dwell where they publish,
Chain by chain, the priorities flourish,
Explicit first, then sources align,
Rules then defaults—a conductor's design.
One resolver path, all publishers shine! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title refers to moving the PriorityResolver chain to the publisher side and ensuring all PublishX paths pass through it, which aligns with the main refactoring objective of this PR.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #391: resolver file moved to publisher package [#391], all PublishX paths unified through publisher.buildMessage [#391], ExplicitPriorityResolver registered first in chain [#391], and PoolManager updated to use publisher.PriorityResolver [#391].
Out of Scope Changes check ✅ Passed All changes are directly related to the refactoring objectives: resolver relocation, PublishX unification through buildMessage, PoolManager type updates, and chain composition wiring in main.go are all within scope.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#391/publisher-resolver

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@internal/processor/fetcher/worker/manager.go`:
- Around line 168-172: PoolManager.Publish currently calls
m.resolver.Resolve(job) unconditionally which panics when m.resolver is nil;
change Publish to guard that call by checking m.resolver != nil before invoking
Resolve and only assign priority when the resolver exists, otherwise leave
priority nil/zero so Publisher.buildMessage (which accepts a nil resolver) can
run the fallback path; update references in Publish to use the guarded priority
variable and ensure no other code paths assume Resolve was called.
🪄 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: 65b8d120-45b6-4f56-886b-397c9c00010d

📥 Commits

Reviewing files that changed from the base of the PR and between d83bcbf and 270cfe0.

📒 Files selected for processing (5)
  • cmd/issuetracker/main.go
  • internal/processor/fetcher/worker/manager.go
  • internal/publisher/chain.go
  • internal/publisher/publisher.go
  • internal/publisher/resolver.go

Comment thread internal/processor/fetcher/worker/manager.go
…t Major)

CodeRabbit 피드백:
- publisher.buildMessage 가 nil resolver 를 fail-safe 로 허용하지만, manager.Publish 의
  로깅용 m.resolver.Resolve(job) 호출은 무조건적 → 테스트 wiring (nil resolver) 에서 panic.
- nil resolver 시 job.Priority 를 그대로 사용 — publisher 의 fail-safe 정책과 일관.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request centralizes priority resolution logic within the publisher package, moving it from the worker package to ensure a single source of truth for all publishing paths. The PriorityResolver chain is now integrated into the buildMessage helper, and an ExplicitPriorityResolver has been added to preserve pre-defined job priorities. Feedback from the review highlights a redundant priority calculation in the PoolManager's Publish method used for logging and points out potential side effects caused by buildMessage modifying the Priority field of the CrawlJob pointer, suggesting improved documentation or API refinement to clarify this behavior.

Comment thread internal/processor/fetcher/worker/manager.go
Comment thread internal/publisher/publisher.go
…edium)

gemini 피드백:
- publisher.buildMessage 가 외부 주입된 *job 의 Priority 를 직접 수정 → 호출자가 원본
  보존을 기대할 경우 의도치 않은 부작용. PublishChained / PublishSeed 같은 내부 생성
  job 은 문제 없으나 PublishJob 으로 외부 job 을 발행할 때 surprise side effect.
- local 복사본 (j := *job) 의 Priority 만 갱신하고 Marshal / Topic / Headers 모두 j 기준
  으로 구성. CrawlJob 은 작은 struct 이라 복사 비용 무시 가능.
- manager.Publish 의 로깅용 m.resolver.Resolve(job) 평가는 job 미수정이라 publisher 의
  side-effect-free buildMessage 와 일관 — 양쪽 결과 동일 (resolver idempotent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] PriorityResolver chain → publisher 측 이동 + 모든 PublishX 통과 (#385 Sub 6)

2 participants