무엇이·왜·어떻게 바뀌었나 + 바뀐 수집 시퀀스
crawler-lib-golang · 2026-05 · 기반: go-missing-index-path 분석index Path(소문자) ↔ LOWER(PRODUCT_KEY)로 비교 → "누락"으로 찍혔지만, 실제 누락이 아니라 식별·해결 문제였다.ai_ci), 목록에 버전 미저장.go.mod로 진짜 module path 해결 + proxy 기준 존재 판단 + 대소문자 구분 저장.최초 분석(docs/go-missing-index-path-report.md)의 핵심: 누락 점검 스크립트의 비교 기준은 이랬다.
따라서 "not found"는 "Go 모듈이 실제로 없음"이 아니다. 정확히는 "index path를 소문자로 만든 값과 같은 PRODUCT_KEY가 DB에 없음"일 뿐이다.
Go의 진짜 키는 go.mod의 module 라인에 선언된 값(declared module path)이다. 그래서 index가 준 Path는 수집 후보로만 보고, worker가 proxy.golang.org/{path}/@v/{version}.mod를 확인해 선언된 module path를 대표 PRODUCT_KEY로 저장해야 한다.
processed=6 의 의미 — "수집 실패"가 아니라 "이 index path는 대표 키가 아니라서, go.mod에 선언된 module path 쪽으로 저장했다"는 표시.| 항목 | 기존 (V1) | 변경 (V2) |
|---|---|---|
| 목록 테이블 grain | index path 1개당 1행, 버전 미저장 | (INDEX_PATH, INDEX_VERSION) 이벤트당 1행, 버전 저장 |
| 식별 · 중복 비교 | LOWER() 비교 (대소문자 무시) | 해시 PK sha256(path@version) + 식별 컬럼 as_cs |
| 대표 키(PRODUCT_KEY) | index path를 그대로 | go.mod의 declared module path |
| 존재 판단 기준 | pkg.go.dev 의존 → 404면 누락 오판 | proxy(@v/list→@latest). pkg.go.dev는 metadata만 |
| alias/.git·subpath·declared-diff | 미해결 → "누락"으로 빠짐 | 분류 후 declared로 저장, index행 processed=6 |
| 대소문자 다른 모듈 | ai_ci로 한 행에 합쳐져 손실 | gatheringdb as_cs 테이블로 둘 다 보존 |
| 재수집 | 개념 약함 | RESYNC 컬럼(이벤트별) / GO_RESYNC_ALL(전체) |
| 저장 위치 | labradordb (ai_ci) | gatheringdb (as_cs, Go 전용) |
분석 보고서의 실제 사례를 패턴으로 묶은 것. 모두 "진짜 없음"이 아니라 식별/해결 문제였다.
| 패턴 | 실제 예시 | V2 처리 |
|---|---|---|
| proxy만 있음 (pkg.go.dev 404) | codeberg.org/go-toolbox/xcodeberg.org/elbtech/polival | proxy 기준 수집. @v/list 비면 @latest 한 개만 저장. metadata는 빈값 가능 |
| declared가 index에 없음 | …/juxianjinggan/src →2024-contexts.shylinux.com/x/juxianjinggan | index path로 fetch한 버전을 쓰되 저장 키만 declared로. index행 processed=6 (declared 자체 proxy는 404라 재조회 불가) |
alias .git / repo≠module | …/go-latex/latex.git → …/latexcodeberg.org/godoc/godocs.io → godocs.io | 대표는 module path 하나. alias/repo path 행은 processed=6 |
| subpath(하위 패키지) | 41.neocities.org/diana/widevine → …/diana | .mod의 module root를 대표 키로 저장 |
| 대문자 포함 | eduVPN/vpn-ca, goern/HookedGo | 별개 모듈로 보존. proxy 조회는 대문자를 !+소문자로 escape (edu!v!p!n) |
| 중복 index 이벤트 | 같은 path 여러 번 | 중복 제거 후 1회만 판단 |
Path 받음 (버전은 목록에 안 남김)Path.lower() ↔ LOWER(PRODUCT_KEY) 비교로 존재 확인→ alias/.git·subpath·declared-diff·proxy-only가 누락되거나 잘못된 키로 저장. 대소문자 다른 모듈은 합쳐짐.
(INDEX_PATH, INDEX_VERSION) claimRESYNC=1이면 건너뛰고 재수집)go.mod fetch (없으면 @latest fallback)module 라인 → declared. store = declared or indexprocessed=1, 다르면 processed=6, deprecated=1! escape — 이건 기존·변경 공통 규칙)| 소스 | 기존 역할 | 변경 역할 |
|---|---|---|
index.golang.org | 목록(후보) 제공 | 목록(후보) 제공 — 동일 |
proxy.golang.org | 보조 | 존재의 기준 (@v/list→@latest) |
pkg.go.dev | 존재 판단에 사용 → 404면 누락 오판 | metadata 보강만 (404여도 proxy 있으면 수집) |
index path를 소문자로 비교하던 방식에서 → 이벤트 단위 큐 + go.mod로 진짜 module path 해결 + proxy 기준 존재 판단 + 대소문자 구분 저장으로 바꿔, 누락·오저장·대소문자 손실을 없앴다.