fix(tradein/yandex): newbuilding resolve/fetch_jk через пул прокси + стоп на пустом пуле (#3197, точки 2-3) #3389

Merged
bot-backend merged 2 commits from fix/3197-yandex-newbuilding-proxy-pool into main 2026-09-06 02:24:45 +00:00
Collaborator

Часть #3197 (часть 1, точки 2-3 — обе в providers/yandex/newbuilding.py). Не закрывает issue (остаётся admin.py:702 debug-ручка и часть 2 — не нужна ни на одной из подключённых точек).

Дефект. resolve_yandex_jk_slug (newbuilding.py:~189) и YandexNewbuildingScraper.fetch_jk (:~385) строили BrowserFetcher(source="yandex", endpoint=…) без пула → env-фолбэк SCRAPER_PROXY_URL = выключенный узел 9 (407) → camoufox InvalidIP (#3386). proxy_provider до задачи не доезжал ни по одной ветке: SchedulerContext.proxy_provider есть, но _job_yandex_newbuilding_sweep его не читал, а enrich_yandex_newbuilding_sweep не принимал. Ближайший yandex_newbuilding_sweep — 07.09 03:58 UTC.

Фикс. Обе точки — build_browser_fetcher(config, "yandex", proxy_provider=…) (как yandex/serp.py:566), kwarg-only proxy_provider=None; config=None (офлайн-парс-тесты) — прежняя ветка. В задаче RealProxyProvider() конструируется как у соседей (cian_history_backfill.py:221, domclick_detail_backfill.py:406), публичная сигнатура не расширена; admin.py:1947_kit_proxy_provider(). Обе точки kit глотали NoProxyAvailableError (except Exception → return None, тот же дефект, что #3382) — пробрасывается через caused_by_no_proxy, в задаче no_proxy_stop=True + break, mark_failed в _job_yandex_newbuilding_sweep; флаг читается из counters. Часть 2 (тёплый контекст) не нужна: reuse_context на этом пути не включён.

Тесты: tests/test_3197_yandex_newbuilding_proxy_pool_wiring.py — обе точки строят фетчер с провайдером (захват на _base.BrowserFetcher), стоп на пустом пуле через живые resolve_yandex_jk_slug/fetch_jk (мокнут только BrowserFetcher.fetch). Чужой test_scraper_kit_newbuilding_endpoint.py — спай переехал на _base.BrowserFetcher (как #2767 для cian-близнеца).

Фальсификация: откат всех хунков → assert 0 == 2 (обе точки обязаны строить фетчер) и TypeError … 'no_proxy_stop'; отдельная мутация «вернуть только глотание в kit» → к сайдкару ходили ровно один раз: assert 3 == 1 — три дома вместо одного. Восстановлено.

Прогоны: полный backend 5514 passed, 35 skipped (rc=0); ruff OK.

Приёмка на проде (окно yandex_newbuilding_sweep 07.09 03:58 UTC): в логе сайдкара [yandex] … override=True (старый путь не слал proxy в теле вовсе); succeeded > 0/rows_inserted > 0 в counters, InvalidIP = 0; обратное направление — при пустом пуле failed + no_proxy_stop=true после одного дома.

Часть #3197 (часть 1, точки 2-3 — обе в `providers/yandex/newbuilding.py`). Не закрывает issue (остаётся `admin.py:702` debug-ручка и часть 2 — не нужна ни на одной из подключённых точек). **Дефект.** `resolve_yandex_jk_slug` (`newbuilding.py:~189`) и `YandexNewbuildingScraper.fetch_jk` (`:~385`) строили `BrowserFetcher(source="yandex", endpoint=…)` без пула → env-фолбэк `SCRAPER_PROXY_URL` = выключенный узел 9 (407) → camoufox `InvalidIP` (#3386). `proxy_provider` до задачи не доезжал ни по одной ветке: `SchedulerContext.proxy_provider` есть, но `_job_yandex_newbuilding_sweep` его не читал, а `enrich_yandex_newbuilding_sweep` не принимал. Ближайший `yandex_newbuilding_sweep` — 07.09 03:58 UTC. **Фикс.** Обе точки — `build_browser_fetcher(config, "yandex", proxy_provider=…)` (как `yandex/serp.py:566`), kwarg-only `proxy_provider=None`; `config=None` (офлайн-парс-тесты) — прежняя ветка. В задаче `RealProxyProvider()` конструируется как у соседей (`cian_history_backfill.py:221`, `domclick_detail_backfill.py:406`), публичная сигнатура не расширена; `admin.py:1947` — `_kit_proxy_provider()`. Обе точки kit глотали `NoProxyAvailableError` (`except Exception → return None`, тот же дефект, что #3382) — пробрасывается через `caused_by_no_proxy`, в задаче `no_proxy_stop=True` + `break`, `mark_failed` в `_job_yandex_newbuilding_sweep`; флаг читается из `counters`. Часть 2 (тёплый контекст) не нужна: `reuse_context` на этом пути не включён. **Тесты:** `tests/test_3197_yandex_newbuilding_proxy_pool_wiring.py` — обе точки строят фетчер с провайдером (захват на `_base.BrowserFetcher`), стоп на пустом пуле через живые `resolve_yandex_jk_slug`/`fetch_jk` (мокнут только `BrowserFetcher.fetch`). Чужой `test_scraper_kit_newbuilding_endpoint.py` — спай переехал на `_base.BrowserFetcher` (как #2767 для cian-близнеца). **Фальсификация:** откат всех хунков → `assert 0 == 2` (обе точки обязаны строить фетчер) и `TypeError … 'no_proxy_stop'`; отдельная мутация «вернуть только глотание в kit» → `к сайдкару ходили ровно один раз: assert 3 == 1` — три дома вместо одного. Восстановлено. **Прогоны:** полный backend `5514 passed, 35 skipped` (rc=0); ruff OK. **Приёмка на проде (окно `yandex_newbuilding_sweep` 07.09 03:58 UTC):** в логе сайдкара `[yandex] … override=True` (старый путь не слал `proxy` в теле вовсе); `succeeded > 0`/`rows_inserted > 0` в counters, `InvalidIP` = 0; обратное направление — при пустом пуле `failed` + `no_proxy_stop=true` после одного дома.
bot-backend added 1 commit 2026-09-06 00:57:05 +00:00
fix(#3197): yandex newbuilding — обе точки в пул прокси + стоп на пустом пуле
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m56s
cb5714fff0
`YandexNewbuildingScraper.fetch_jk` и `resolve_yandex_jk_slug` строили
`BrowserFetcher(source="yandex", endpoint=...)` без proxy_provider/use_pool/
environment — сайдкар брал env-узел SCRAPER_PROXY_URL, на проде выключенный
(407 → camoufox InvalidIP → /fetch 503, факт #3386), то есть путь шёл мимо пула
целиком, а прод-отказ «пул пуст» (#2616) был мёртв: он смотрит на environment,
который до конструктора не доезжал. Обе точки собраны через
build_browser_fetcher(config, "yandex", proxy_provider=...), как yandex/serp.py.

Второе: общий `except Exception` в обеих функциях глотал NoProxyAvailableError и
возвращал None — прогон, не ходивший к площадке, перебирал все ЖК и уходил в
'done'. Теперь «пул пуст» пробрасывается наружу (caused_by_no_proxy), sweep
обрывается на первом доме с no_proxy_stop, а прогон финализируется как failed
(образец дефекта — #3382, cian/detail.py).
Author
Collaborator

Code-review (07.09): — обе точки через build_browser_fetcher (третьего места нет), контракт None для httpx/парс-ошибок цел, стоп на обоих сайтах, ветка no_proxy_stop в хендлере первая (порядок сиблинга scheduler.py:164-184), мутация «снять raise» воспроизведена (assert 3 == 1 на обоих параметрах), старые тесты не ослаблены (test_2860 не тронут; утверждение про endpoint сохранено дословно), blast radius — два вызывающих, оба совместимы.

Докатываю до мержа три мелочи: no_proxy_stop в counters как 1 (у соседей 1, здесь уезжал JSON true — SQL-монитор по = '1' промахнулся бы мимо Яндекса), logger.error → info на финальной строке хендлера (как scheduler.py:172-176), устаревший докстринг фабрики _base.py:209-218. Не в этом PR: admin-ручка :1951 при пустом пуле отдаст 500 вместо 503 (честнее прежнего 404, но стектрейс в GlitchTip).

Code-review (07.09): ✅ — обе точки через `build_browser_fetcher` (третьего места нет), контракт `None` для httpx/парс-ошибок цел, стоп на обоих сайтах, ветка `no_proxy_stop` в хендлере первая (порядок сиблинга `scheduler.py:164-184`), мутация «снять `raise`» воспроизведена (`assert 3 == 1` на обоих параметрах), старые тесты не ослаблены (`test_2860` не тронут; утверждение про endpoint сохранено дословно), blast radius — два вызывающих, оба совместимы. Докатываю до мержа три мелочи: `no_proxy_stop` в counters как `1` (у соседей `1`, здесь уезжал JSON `true` — SQL-монитор по `= '1'` промахнулся бы мимо Яндекса), `logger.error → info` на финальной строке хендлера (как `scheduler.py:172-176`), устаревший докстринг фабрики `_base.py:209-218`. Не в этом PR: admin-ручка `:1951` при пустом пуле отдаст 500 вместо 503 (честнее прежнего 404, но стектрейс в GlitchTip).
Light1YT added 1 commit 2026-09-06 01:27:50 +00:00
fix(#3197): no_proxy_stop=1 как у соседей, INFO на финале хендлера, докстринг фабрики
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m57s
939a8a1646
bot-backend merged commit 3fe2d310b2 into main 2026-09-06 02:24:45 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3389
No description provided.