fix(tradein/scrapers): wire proxy_pool into Avito legacy pipeline, rotate on ban (#2202) #2328
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2328
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2202-proxy-pool-rotate-exclude"
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?
Summary
Issue #2202 (P0):
proxy_pool.pyв шапке прямо писал, что ни один боевой скрейпер не подключён —git grep "acquire("по scrapers/scrape_pipeline.py давал 0 хитов. Скрейперы читали статическийsettings.scraper_proxy_url— один mobile-IP на все источники, бан на общем IP выносил avito+cian+yandex+domklik разом.Подключён pool-aware acquisition/rotation в 3 curl-режим Avito entry points (
run_avito_pipeline,run_avito_city_sweep,run_avito_newbuilding_sweep), за флагомuse_proxy_pool_curl(defaultFalse— ship-dark, нулевое изменение поведения пока явно не включат).Прошёл 2 раунда review. Раунд 1 нашёл реальный баг (MAJOR):
_rotate_pool_proxyмог молча вернуть тот же прокси, который только что забанил —release(current_lease)вызывался ДОacquire(), и один бан не достигает порога исключения (consecutive_fails=1 < MAX_CONSECUTIVE_FAILS=3), так чтоleased_by IS NULLфильтр не исключал только что освобождённый прокси. Исходный acceptance-тест проходил случайно (id tie-break в фикстуре). Fix:release()перенесён строго ПОСЛЕacquire()— пока current_lease не освобождён, фильтр гарантированно его исключает независимо от id/last_ok_at. Добавлен зеркальный regression-тест с обратным id-порядком; раунд 2 review независимо воспроизвёл регресс (временно откатил порядок, увидел тест красным, откатил обратно) — подтверждено, не на слово.Out of scope (задокументировано, не эта задача)
tradein-mvp/browser/server.py), уже имеют per-source dedicated proxy-аккаунты для avito/cian/yandex; DomClick всё ещё падает на общийSCRAPER_PROXY_URLтам — отдельный follow-up.run_avito_full_load— используетAvitoScraperнапрямую (много вызывающего кода за пределами scrape_pipeline: admin endpoints, backfill) — материально больший blast radius, follow-up при необходимости.scrape_proxies, сейчас ~5 строк только для health-checker) — ops-задача, не код.Test plan
test_scrape_pipeline_proxy_pool.py) + regression-guard на именно этот MAJOR-багtest_search_api.py::test_search_cache_hit)proxy_poolне ломает обычный запуск скрейпераRefs #2202
Боевой оркестратор (scrape_pipeline.py) читал только статический settings.scraper_proxy_url — ни один боевой скрейпер не использовал proxy_pool/scrape_proxies (git grep "acquire(" = 0 хитов). Бан на общем IP выносил avito+cian+yandex+domklik разом. Подключён pool-aware proxy acquisition/rotation в 3 curl-режим Avito entry points (run_avito_pipeline, run_avito_city_sweep, run_avito_newbuilding_sweep), за флагом use_proxy_pool_curl (default False — ship-dark, поведение не меняется пока явно не включат): - _pool_proxy_dict(): health-filtered acquire() lease, fallback на статический прокси при пустом пуле/ошибке/флаге off. - _rotate_pool_proxy(): на бан — mark_health(ok=False) → acquire() замены → ТОЛЬКО ПОСЛЕ release(current_lease). Порядок принципиален: release ДО acquire() позволял пулу молча вернуть тот же только что забаненный прокси (один бан не достигает MAX_CONSECUTIVE_FAILS=3, leased_by IS NULL фильтр не исключал бы его) — найдено на pre-push review, воспроизведено и закрыто регрессионным тестом с CURRENT id ниже GOOD id (оригинальный тест проходил случайно из-за id tie-break). - run_id прокинут в acquire() на обоих sweep call sites — scrape_proxies .leased_by несёт реальный run id для диагностики, не NON_RUN_LEASE_MARKER. Cian/Yandex/DomClick (browser-mode, отдельный сервис) и run_avito_full_load (использует AvitoScraper напрямую, много вызывающих кода за пределами scrape_pipeline) — вне скоупа, задокументировано как follow-up в PR description. Refs #2202