fix(scraper-kit): резюм exhaustive не пере-пробивает готовые полосы — containment по done-леджеру до пробы, 17 911 запросов → 0 #3358
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3358
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/3315-exhaustive-containment-skip"
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?
Closes #3315. Резюм
avito_full_load_exhaustiveчестно зачитывал done-корзины, но бисекция пере-пробивала поддиапазоны ВНУТРИ готовых полос живыми запросами (skip проверялся в листе, после probe) — на пуле из 1-2 нод бан-бюджет сгорал на готовой территории, прогресс за три прогона — ноль.Где встал гейт
Не в avito-ветках, а на входе в узел рекурсии общего движка:
walk_price_range(pricing/bisection.py) получилshould_skip: SkipFn | None, проверяемый первой строкой ДОprobeи проброшенный во все 4 рекурсивных вызова — покрытое поддерево обрезается на любой глубине. Avito (serp.py) строит предикат один раз на комнатность. Другие провайдеры не тронуты (None= прежнее поведение); лист-скип по точному ключу оставлен для инкрементального пути.Покрытие (
done_range_skipper)Ключ
label:lo:hi(включительно;hi=open→ +inf); только ключи своего label, битые пропускаются (не покрывают, обход не роняют); отрезки сливаются приlo <= prev_hi + 1— пересекающиеся И смежные (половины бисекции лежат встык, без «+1» шов пробивался бы заново); True, если один слитый отрезок содержит[q_lo, q_hi]. Пустой/чужой леджер → гейт не ставится.Тесты
test_3315_avito_exhaustive_containment_skip.py:48 passed(-k avito serp/exhaustive/checkpoint/bisect) +92 passed(-k bisect/pricing/parity — golden-parity cian/yandex цела). Фальсификация (откат исходников):полоса [4062500, 4124999] внутри зачтённой [4000000, 4999999], а обход сходил в сеть 3 раз(а),[4.5М, 5.5М] в объединении двух смежных корзин — 63 раз(а),резюм готовой комнатности сделал 17911 запрос(ов) вместо нуля— все по значению счётчика fetch.Честные оговорки
should_skipне переведены — тот же дефект вероятен, отдельный issue;Прод-приёмка
Следующий резюм-прогон exhaustive: в логе нет
total=None for room_studii [4062500…]-проб внутри done-полос; число запросов до первой новой корзины — единицы, не десятки.Deep-ревью (после мержа, для записи): ✅ — property-прогон 100k случайных леджеров против оракула «множество покрытых точек»: 0 ложных skip;
label:0:openне покрывает несобранное, потому что ключ попадает в леджер только приcomplete=True(serp.py:1628).Несущая предпосылка, которую стоит держать в голове (не блокер):
run_avito_full_loadобслуживает оба режима одним леджеромdone_buckets; инкрементальные ключи — целые seed-брекеты, их объединение =[0, ∞)на комнатность. Exhaustive-резюм с такого леджера пропустил бы комнатность целиком. Сегодня это блокирует_pick_resume(scheduler.py:588-604, 672-689: кандидат обязан иметьparams IS NOT DISTINCT FROMтекущих). Containment усиливает цену будущего послабления этого гейта с «перескрапим лишнего» до «молча пропустим комнатность» — при правке_pick_resumeперечитатьdone_range_skipper.Побочно замечено (пред-существующее): комментарий
serp.py:1266«pmax эксклюзивный сверху» расходится с арифметикой (везде hi включительно) — если pmax правда эксклюзивен, точкаmidтерялась и до этого PR.Follow-up на cian/yandex — #3359.