NoProxyAvailableError — наследник RuntimeError, поэтому в run_avito_full_load /
run_cian_full_load / run_yandex_full_load он попадал в общую ветку `except
RuntimeError` → mark_failed. mark_failed, в отличие от mark_banned, НЕ пишет
done_buckets: чекпоинт всех пройденных бакетов терялся ровно на НАШЕМ отказе —
том исходе, для которого #2686 явно требовал его сохранять наравне с блокировкой
площадкой. Плюс ban_kind_of_exception отдавал для него 'unknown', хотя причина
здесь не «не установлена», а названа самим типом (proxy_errors.py: «это НАША
инфраструктура (нет живого прокси), не внешний блок»).
Достижимость на проде (замер 12.08, read-only): под avito доступны три узла
(id 9/10/11; id 1 забанен парой до 13.08). BrowserFetcher меняет lease после
_LEASE_ROTATE_AFTER_FAILS=3 подряд неудачных /fetch, а proxy_pool.acquire не
выдаёт узел с consecutive_fails >= MAX_CONSECUTIVE_FAILS=3 — девять неудачных
POST'ов опустошают пул под источник. Лестница одного полного обхода при
отказывающем сайдкаре делает до 24 POST'ов (4 бакета × 3 попытки × 2 внутренних
httpx-ретрая), то есть проходит через это состояние заведомо. Цена — прогон 3547
(09.08): 35 бакетов, 5496 объявлений за 2ч58м.
Refs #2687, #2686