feat(tradein): checkpoint/resume for yandex full-load — survive restart (#930) #937
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#937
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/yandex-fullload-checkpoint-resume"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up к #931. Checkpoint/resume-коммит был запушен в ветку #931 после того как reviewer уже squash-смерджил #931 (только exhaustive-коммит попал в main) — squash-merge timing trap. Этот PR доносит orphaned checkpoint-работу (cherry-pick
3bcfb6b→d45018fповерх текущего main). Зеркало Cian #932.Summary
yandex_realty.py—fetch_all_secondary/_walk_price_rangeпринимаютskip_buckets: set[str] | None.bucket_key = "{rooms}:{lo}:{hi}". Skip пропускает только пагинацию + on_bucket (probe/split-решение остаются). Применено к обоим leaf-путям Yandex: нормальному параллельному иtotal is Nonepaginate-until-empty fallback. Callback →on_bucket(bucket_key, lots).scrape_pipeline.py—run_yandex_full_load(resume_run_id: int | None = None). При resume читаетdone_bucketsиз counters прошлого run (SELECT counters FROM scrape_runs WHERE id = CAST(:rid AS bigint)), сидит skip-set._on_bucket(bucket_key, lots)дописывает вdone+ heartbeat{**counters, "done_buckets": sorted(done)}(включая пустой-lots бранч).mark_doneв обоих ветках (success + cancelled) включаетdone_buckets→ resumed-run сам резюмируем.mark_failed— без.admin.py—YandexFullLoadRequest.resume_run_id: int | None, проброшен вrun_yandex_full_load. Без него — full walk с нуля.Test plan
ruff check(3 файла) → All checks passedpytest -k "yandex or full_load"→ 306 passed (на актуальном main-базисе после cherry-pick, не доверяя прошлому прогону — перепрогнал сам)test_skip_buckets_skips_pagination_and_on_bucket,test_on_bucket_receives_key_and_lots+ обновлены existing on_bucket-стабы под 2-арг сигнатуру.Refs #930 (Yandex-половина; Cian-половина уже в main = #932). Не запускалось против prod.
✅ APPROVE — faithful mirror одобренного #932 на yandex, sig-change консистентен. Мержу.
Verified (урок #919 — cross-callsite sig consistency)
on_bucket1-arg→2-arg(bucket_key, lots)изменён во всех yandex call-site'ах: оба leaf-пути (normal parallel +total=Nonefallback) +run_yandex_full_load._on_bucket. Test-стабы обновлены на 2-arg → нет осиротевших 1-arg вызовов (автор перепрогнал 306 passed на текущем main).skip_bucketsпроброшенfetch_all_secondary→_walk_price_range(обе ветки рекурсии + оба leaf-пути); skip-check post-probe/pre-pagination в обоих leaf'ах.bucket_key = "{rooms}:{lo}:{hi}".resume_run_idчитаетcountersчерезCAST(:rid AS bigint)(psycopg-v3);doneкопится;mark_doneнесётdone_bucketsв success+cancel ветках._on_bucket(уже 2-arg из #932) не задет, коллизии нет.🟡 Advisory (как в #932)
bucket_keyсовпадёт на resume только если split-дерево идентично между прогонами (totalItems/fallback дрейфует) — mismatched бакеты re-paginate, dedup гасит. Best-effort.Squash-merge + delete branch. Закрывает Yandex-половину #930 (Cian = #932 в main).