tradein: «пул пуст на старте батча» у cian/domclick detail-бэкфиллов уходит мимо no_proxy_stop — scheduler пишет failed со стухшими counters #3384

Closed
opened 2026-09-05 21:47:39 +00:00 by bot-backend · 1 comment
Collaborator

Находка code-review PR #3382 (#3197), общая для двух бэкфиллов, не регрессия ветки.

Факт. BrowserFetcher._acquire_lease() живёт в __aenter__ (scraper_kit/browser_fetcher.py:~444). Если пул пуст до первого объявления, NoProxyAvailableError вылетает из async with BrowserFetcher(...) — у app/tasks/cian_history_backfill.py:~218 и у app/tasks/domclick_detail_backfill.py:~403 — мимо всей стоп-механики внутри цикла (caused_by_no_proxyno_proxy_stop, break). Scheduler ловит это общим except Exception (app/services/scheduler.py:~206 для cian; аналог у domclick) и пишет mark_failed со стухшими нулевыми counters и без no_proxy_stop. Статус честный (failed), диагноз теряется: SQL-разбор простоя по counters.no_proxy_stop (#3288 п.2, #3367) этот случай не найдёт.

Для сравнения avito_detail_backfill после #3367 распознаёт пустой пул и на входе (проверить и записать сюда, где именно).

Чинить: ловить NoProxyAvailableError вокруг async with (или в scheduler по цепочке причин через общий caused_by_no_proxy) → те же counters.no_proxy_stop=1 + mark_failed("пул прокси пуст — к площадке не ходили"), что и внутри цикла. Тест — через настоящий async with BrowserFetcher с провайдером, чей acquire поднимает NoProxyAvailableError (не мок самого бэкфилла).

Приёмка: прогон с пустым пулом на старте — status='failed', counters.no_proxy_stop=1, attempted=0; тест краснеет на текущем main.

Refs #3197, PR #3382, #3283, #3288.

Находка code-review PR #3382 (#3197), общая для двух бэкфиллов, не регрессия ветки. **Факт.** `BrowserFetcher._acquire_lease()` живёт в `__aenter__` (`scraper_kit/browser_fetcher.py:~444`). Если пул пуст **до первого объявления**, `NoProxyAvailableError` вылетает из `async with BrowserFetcher(...)` — у `app/tasks/cian_history_backfill.py:~218` и у `app/tasks/domclick_detail_backfill.py:~403` — мимо всей стоп-механики внутри цикла (`caused_by_no_proxy` → `no_proxy_stop`, `break`). Scheduler ловит это общим `except Exception` (`app/services/scheduler.py:~206` для cian; аналог у domclick) и пишет `mark_failed` со **стухшими нулевыми counters** и без `no_proxy_stop`. Статус честный (`failed`), диагноз теряется: SQL-разбор простоя по `counters.no_proxy_stop` (#3288 п.2, #3367) этот случай не найдёт. Для сравнения `avito_detail_backfill` после #3367 распознаёт пустой пул и на входе (проверить и записать сюда, где именно). **Чинить:** ловить `NoProxyAvailableError` вокруг `async with` (или в scheduler по цепочке причин через общий `caused_by_no_proxy`) → те же `counters.no_proxy_stop=1` + `mark_failed("пул прокси пуст — к площадке не ходили")`, что и внутри цикла. Тест — через настоящий `async with BrowserFetcher` с провайдером, чей `acquire` поднимает `NoProxyAvailableError` (не мок самого бэкфилла). **Приёмка:** прогон с пустым пулом на старте — `status='failed'`, `counters.no_proxy_stop=1`, `attempted=0`; тест краснеет на текущем main. Refs #3197, PR #3382, #3283, #3288.
Author
Collaborator

PR #3388 смержен и задеплоен (07.09 ~01:50 UTC, BUILD_SHA=3fe2d31; no_proxy_stop в app/services/scheduler.py контейнера scraper — 6 вхождений). У cian в mark_failed уезжает последний снимок heartbeat + флаг (app-копия mark_failed заменяет counters — #3390). Приёмка событийная: первый прогон cian/domclick/avito при пустом пуле на старте — failed + no_proxy_stop=1 + attempted=0, в логах proxy_pool acquire(<source>) empty in production — refusing.

PR #3388 смержен и задеплоен (07.09 ~01:50 UTC, `BUILD_SHA=3fe2d31`; `no_proxy_stop` в `app/services/scheduler.py` контейнера scraper — 6 вхождений). У cian в `mark_failed` уезжает последний снимок heartbeat + флаг (app-копия `mark_failed` заменяет counters — #3390). Приёмка событийная: первый прогон cian/domclick/avito при пустом пуле на старте — `failed` + `no_proxy_stop=1` + `attempted=0`, в логах `proxy_pool acquire(<source>) empty in production — refusing`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#3384
No description provided.