Skip to content

[REFAC#387] scheduler.JobEmitter → publisher.PublishSeed 이동 (#385 Sub 2) - #395

Merged
juhy0987 merged 3 commits into
mainfrom
refactor/#387/publisher-seed
May 12, 2026
Merged

juhy0987 merged 3 commits into
mainfrom
refactor/#387/publisher-seed

Conversation

@juhy0987

Copy link
Copy Markdown
Member

연관 이슈


구현 내용

#385 (Publisher 통합 모듈화 메타) Sub 2 — 시드 발행 책임을 publisher facade 로 흡수. 시드 / chained 가 동일 guard / normalizer / producer 를 공유하여 단일 책임 완성.

신규 (publisher)

파일 내용
`publisher/seed.go` (신규) `PublishSeed(ctx, *core.CrawlJob) error` 메소드 + `ErrPublishSkipped` sentinel + `releaseGuardOnFailure` 헬퍼
`publisher/guard.go` `PipelineGuard` 인터페이스에 `Release` 메소드 추가 (시드 발행 전용)

제거 (scheduler)

  • `internal/scheduler/emitter.go` 파일 삭제
    • `Emitter` 인터페이스 / `JobEmitter` struct / `ErrEmitSkipped` / `PipelineGuard` / `crawlTopic` 함수 모두 제거
  • `scheduler/throttle.go` 에 `crawlTopic` helper 만 잔존 (backlog 조회 전용)

scheduler 의존성 변경

  • `scheduler.Scheduler.emitter Emitter` → `publisher SeedPublisher`
  • `SeedPublisher` interface 신규 (`source.go`) — `publisher.Publisher` 가 구조적 타이핑 만족
  • `scheduler.New()` 시그니처: `emitter Emitter` → `pub SeedPublisher`
  • `s.emitter.Emit(ctx, job)` → `s.publisher.PublishSeed(ctx, job)`
  • `ErrEmitSkipped` 비교 → `publisher.ErrPublishSkipped`

cmd/issuetracker/main.go wiring

  • `scheduler.NewJobEmitter` 호출 제거 + `emitter.SetGuard` / `emitter.SetNormalizer` 제거
  • `jobPublisher` 가 이미 `SetPipelineGuard` + `SetNormalizer` 받음 → chained 와 동일 guard/normalizer 공유 (단일 facade)
  • `scheduler.New(entries, jobPublisher, ...)` 직접 의존

테스트

  • `mockEmitter` / `countEmitter` / `gateMockEmitter` 의 `Emit` 메소드 → `PublishSeed` (인터페이스 구조적 타이핑 만족)

CI / 머지 게이트 점검

변경 영향 범위

  • 영향: `internal/publisher/`, `internal/scheduler/` (emitter.go 삭제), `cmd/issuetracker/main.go`, scheduler 테스트
  • 위험도: Medium — scheduler 의 핵심 dependency 교체 + 161 라인 삭제

검증

  • `go build ./...` 통과
  • `go vet ./...` 통과
  • 전체 38 패키지 `go test -race -count=1` (clean cache) 통과

Required Status Checks

  • 통과 확인 대상:
    • `Commit Lint` / `PR Title Lint` / `Linked Issue Check` / `Format Check` / `Build` / `Test` / `Lint`

롤백 계획

  • PR revert — emitter.go 복원 + scheduler/scheduler.go 의존성 reverse

TODO

  • (없음) Sub 2 scope 완료

논의 사항

🤖 Generated with Claude Code

#385 (Publisher 통합 모듈화 메타) Sub 2 — 시드 발행 책임을 publisher facade 로 흡수.

신규 (publisher):
- publisher/seed.go: PublishSeed(ctx, *core.CrawlJob) 메소드
  · 구 scheduler.JobEmitter.Emit 의 책임 흡수 (guard CheckAndAcquire,
    Normalizer 적용, marshal + producer.Publish, release on publish error)
  · ErrPublishSkipped sentinel (구 scheduler.ErrEmitSkipped 이동)
  · releaseGuardOnFailure 헬퍼
- guard.go: PipelineGuard 인터페이스에 Release 메소드 추가 (시드 발행 전용)

제거 (scheduler):
- internal/scheduler/emitter.go 파일 삭제
- Emitter 인터페이스 / JobEmitter struct / ErrEmitSkipped / PipelineGuard /
  crawlTopic 함수 모두 제거
- scheduler/throttle.go 에 crawlTopic helper 만 잔존 (backlog 조회용)

scheduler 변경:
- scheduler.Scheduler.emitter Emitter → publisher SeedPublisher
- SeedPublisher interface 신규 (source.go) — publisher.Publisher 가 구조적
  타이핑으로 만족
- scheduler.New() 시그니처: emitter Emitter → pub SeedPublisher
- s.emitter.Emit(ctx, job) → s.publisher.PublishSeed(ctx, job)
- ErrEmitSkipped 비교 → publisher.ErrPublishSkipped

cmd/issuetracker/main.go wiring:
- scheduler.NewJobEmitter 호출 제거 + emitter.SetGuard/SetNormalizer 제거
- jobPublisher 가 이미 SetPipelineGuard + SetNormalizer 받음 (chained 와 동일
  guard/normalizer 공유 — 단일 facade)
- scheduler.New(entries, jobPublisher, ...) 로 직접 의존

테스트:
- test/internal/scheduler/scheduler_test.go / scheduler_gate_test.go 의
  mockEmitter / countEmitter / gateMockEmitter 의 Emit 메소드 → PublishSeed
  (인터페이스 구조적 타이핑 만족하도록)

검증:
- go build + go vet 통과
- 전체 38 패키지 race test 통과 (clean cache)
Copilot AI review requested due to automatic review settings May 12, 2026 13:54
@coderabbitai

coderabbitai Bot commented May 12, 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 5 minutes and 50 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: 3cdec502-ff7c-48c3-93a5-1dbb6217daac

📥 Commits

Reviewing files that changed from the base of the PR and between ca39b69 and e7c7de8.

📒 Files selected for processing (12)
  • cmd/issuetracker/main.go
  • internal/publisher/guard.go
  • internal/publisher/seed.go
  • internal/scheduler/emitter.go
  • internal/scheduler/scheduler.go
  • internal/scheduler/source.go
  • internal/scheduler/throttle.go
  • test/internal/publisher/seed_test.go
  • test/internal/scheduler/refresh_test.go
  • test/internal/scheduler/scheduler_gate_test.go
  • test/internal/scheduler/scheduler_test.go
  • test/internal/scheduler/scheduler_throttle_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#387/publisher-seed

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.

@juhy0987 juhy0987 added the refactor Code refactoring label May 12, 2026

@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 refactors the scheduler by removing the JobEmitter and having the Scheduler depend directly on the publisher.Publisher via a new SeedPublisher interface. This change consolidates publishing logic, including URL normalization and pipeline guard checks, into the publisher package. Review feedback suggests adding a defensive nil check for the job parameter in PublishSeed and ensuring that the pipeline guard release operation is resilient to context cancellation by using context.WithoutCancel.

Comment thread internal/publisher/seed.go
Comment thread internal/publisher/seed.go

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.

Pull request overview

이 PR은 기존 scheduler.JobEmitter(시드 CrawlJob 발행 책임)를 제거하고, 동일 책임을 internal/publisher의 facade(Publisher.PublishSeed)로 이동하여 시드/체이닝 발행 경로가 guard/normalizer/producer를 공유하도록 리팩터링합니다.

Changes:

  • scheduler.JobEmitter 및 관련 코드(internal/scheduler/emitter.go) 삭제, 시드 발행을 publisher.PublishSeed로 이전
  • Scheduler 의존성을 EmitterSeedPublisher로 교체하고, skip sentinel을 publisher.ErrPublishSkipped로 통일
  • cmd/issuetracker/main.go wiring에서 emitter 제거 후 jobPublisher를 scheduler에 직접 주입

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/internal/scheduler/scheduler_test.go Scheduler 테스트 더블을 PublishSeed 기반으로 변경
test/internal/scheduler/scheduler_gate_test.go Gate 테스트 더블을 PublishSeed 기반으로 변경
internal/scheduler/throttle.go emitter 삭제에 따라 backlog 조회용 crawlTopic helper 유지
internal/scheduler/source.go EmitterSeedPublisher 인터페이스로 변경
internal/scheduler/scheduler.go scheduler가 SeedPublisher.PublishSeedpublisher.ErrPublishSkipped를 사용하도록 변경
internal/scheduler/emitter.go 기존 JobEmitter 구현 제거(파일 삭제)
internal/publisher/seed.go 신규: Publisher.PublishSeed + ErrPublishSkipped + guard release 헬퍼 추가
internal/publisher/guard.go PipelineGuardRelease 추가(시드 발행 실패 시 marker 해제용)
cmd/issuetracker/main.go scheduler emitter wiring 제거, jobPublisher 직접 주입

Comment thread test/internal/scheduler/scheduler_test.go Outdated
Comment thread test/internal/scheduler/scheduler_gate_test.go Outdated
Comment thread internal/publisher/seed.go Outdated
Comment thread internal/publisher/seed.go
Comment thread internal/scheduler/scheduler.go
juhy0987 added 2 commits May 12, 2026 23:11
…Cancel

gemini medium 2건 처리:

1) seed.go:32 nil job 방어 (수용)
   - exported method PublishSeed 가 nil pointer 받으면 패닉 → fail-fast 반환
   - errors.New("publish seed: nil job") — caller 가 즉시 인지

2) seed.go:75 release 시 context.WithoutCancel (수용)
   - publish 실패가 ctx cancel 때문이면 release 호출도 같은 cancel 영향 받아
     marker 해제 실패 → 다음 retry 가 false acquired 로 silent skip
   - releaseGuardOnFailure 호출에 context.WithoutCancel(ctx) 적용 — shutdown
     중에도 marker 해제 보장 (drain 패턴 — retry_scheduler 와 일관)

거절 1건 (msg.Topic nil panic 우려):
   - buildMessage 가 queue.Message (value type) 반환 — nil 불가능
   - msg 가 pointer 가 아니므로 msg.Topic 접근 panic 없음
   - 코드 변경 불필요
Copilot 5건 모두 수용:

1) 테스트 더블 이름 (scheduler_test.go / refresh_test.go / scheduler_gate_test.go /
   scheduler_throttle_test.go)
   - mockEmitter → mockPublisher
   - countEmitter → countPublisher
   - gateMockEmitter → gateMockPublisher
   (SeedPublisher 인터페이스 의미와 일치)

2) scheduler_gate_test.go 주석 "Emit 호출 인자" → "PublishSeed 호출 인자
   SeedPublisher 테스트 더블"

3) seed.go releaseGuardOnFailure 의 release 실패 로그 메시지 일반화
   - 구 "after publish error" 는 marshal 실패 분기에서도 호출되어 모호
   - "after marshal/publish failure" 로 정정

4) PublishSeed 전용 단위 테스트 신규 (test/internal/publisher/seed_test.go)
   - TestPublishSeed_NilJob — nil 방어 검증
   - TestPublishSeed_NoGuard_Success — guard 미주입 정상 발행
   - TestPublishSeed_GuardDeny_ReturnsErrPublishSkipped — guard false → 스킵
   - TestPublishSeed_GuardError_FailOpen — guard 에러 시 fail-open
   - TestPublishSeed_PublishFailure_ReleasesGuard — publish 실패 시 release
     호출 (핵심 케이스)

5) scheduler.go 주석 정리
   - "Emitter를 통해 ... 발행" → "SeedPublisher (= publisher.Publisher.PublishSeed)"
   - "Emit 호출 없이 silent drop" → "PublishSeed 호출 없이 silent drop"
   - "emit 직전" → "publish 직전" 등 SeedPublisher 기준 정리

검증:
- go build + go vet 통과
- 전체 37 패키지 race test 통과 (clean cache, FAIL 없음)
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] scheduler.JobEmitter → publisher/seed.go 이동 (#385 Sub 2)

2 participants