fix(tradein/scraper): длинная серия неудач перестаёт замолкать, оборванный прогон — называться успехом (#2670) #2720
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2720
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2670-streak-and-coverage"
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?
1. Анти-спам, запертый в «один раз навсегда»
Оба сторожа слали алерт ровно на N-й подряд неудаче и дальше молчали. Пока источники падали вперемешку с успехами, серия рвалась и алерт взводился заново; у постоянно сломанного источника рваться нечему.
Прод 2026-08-06 — сколько «замолкло»:
avito_full_loadavito_full_load_exhaustiveavito_city_sweep_pervouralskdomclick_city_sweepТо есть 2 источника «замолкли»: алерт был ровно один, на третьей неудаче, а простой продолжается 34 дня.
Опровергнутая предпосылка. Условие прерывания у этого сторожа, в отличие от #2703, достижимо — и по данным прода достигается (
domclick_city_sweep: стрик 1 при 47 завершённых прогонах). Ломается не достижимость, а срок: реальный простой длиннее одного напоминания. Поэтому применён не «сделать условие достижимым» (оно и так), а тот же принцип на другом конце — молчание не должно быть неограниченным.Правка: разреженная лестница вех N, 2N, 4N…, дальше не реже одной на
STREAK_ALERT_MAX_PERIOD × Nпрогонов; достигнутый потолок сканирования сам по себе повод для алерта — «замолчать навсегда» невозможно по построению. Лестница по прогонам, а не календарная: источники идут разным тактом (domclick — раз в сутки, proxy_healthcheck — раз в полчаса), календарное разрежение для одного из них всегда будет либо спамом, либо молчанием. Первый алерт приходит там же, где и раньше.Та же лестница — у сторожа нулей (#2625/#2703): это сиблинги, чинить один и оставить второй значит оставить ту же дыру.
2. Оборванный прогон
Где терялся признак: в цикле
DomClickScraper.fetch_cityпоROOM_BUCKETS—breakна блоке,continueна битом бакете. Наружу он не выходил: метод возвращает голый список лотов, а pipeline писал вcounters.pages_fetchedрасчётную оценкубакеты × страницы— оценку, не измерение. Прогон, прошедший 3 бакета из 6, был неотличим от полного.Правка несёт признак оттуда, где он рождается:
buckets_completed/buckets_totalна самом скрейпере (тот же канал, что уblocked), включая случай снятия фазы по таймауту — ссылка на скрейпер там жива. Честный статус сравнивает собранное с ожидаемым охватом, а не с нулём.Порядок веток: блок →
banned; ноль лотов при ошибках →failed; неполный охват →failed; иначеdone. Охват0/0(скрейпер не успел создаться) вердикта не выдумывает.Сколько «оборвано, но done» на проде: 0 — у всех 26
done-прогонов domclickerrors_count = 0. Это профилактика, как и написано в issue; и она честно измерима только теперь — до правки охват нигде не сохранялся, так что «0» относится к единственному доступному ретро-признаку, а не к охвату.Побочно:
_DOMCLICK_NUM_BUCKETSперестаёт быть вторым литералом рядом сROOM_BUCKETS.Test plan
tests/test_2670_streak_and_partial_coverage.py— 68 тестов, обе копии runs-модуля.Refs #2670