gendesign/tradein-mvp/backend/data/sql/228_scrape_proxies_browser_health.sql
bot-backend 64a7975549
All checks were successful
Deploy Trade-In / changes (push) Successful in 10s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m2s
Deploy Trade-In / build-backend (push) Successful in 1m37s
Deploy Trade-In / deploy (push) Successful in 1m54s
fix(tradein/proxy): проба узла ходит браузерным трактом, вердикт живёт отдельно от HTTP-пробы (#2723) (#2736)
2026-08-06 12:50:24 +00:00

66 lines
5.5 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 228_scrape_proxies_browser_health.sql
-- Здоровье узла ОТДЕЛЬНО для браузерного тракта (#2723).
--
-- WHY:
-- `run_proxy_healthcheck` гоняет через узел обычный httpx-GET к ipify. Боевой сбор
-- Авито с 02.08 (#2637) ходит через сайдкар браузером: camoufox стартует С ЭТИМ
-- прокси (geoip-lookup на launch), потом навигация. Это разные свойства узла:
-- крошечный GET проходит там, где launch/навигация падает (`browser unavailable
-- (proxy may be down)` — все 90 записанных обрывов сбора именно такие).
--
-- Хуже того, оба свойства писались в ОДИН счётчик: боевой /fetch репортит
-- mark_health(ok=False) → consecutive_fails++, но следующая (≤30 мин) успешная
-- ipify-проба делает consecutive_fails=0 + enabled=true. Дешёвая проба СТИРАЛА
-- вердикт дорогого тракта, и узел, мёртвый для браузера, вечно возвращался в
-- выдачу. Это ровно ошибка #2686 (схлопывание двух диагнозов в один флаг) в
-- другом месте; разводим её тем же приёмом, что #2711 (`scrape_runs.ban_kind`) —
-- поле РЯДОМ, а не новое значение существующего флага.
--
-- WHAT (три колонки, ни одна не участвует в enabled/consecutive_fails):
-- browser_fail_streak — подряд-провалы ИМЕННО браузерной пробы, и только те, что
-- атрибутируются узлу (сайдкар лежит / страница пустая —
-- не считаются, см. proxy_pool._classify_browser_probe).
-- Успешная ipify-проба его НЕ обнуляет — в этом весь смысл.
-- browser_unfit_since — момент, когда streak дошёл до порога. NOT NULL = «жив для
-- HTTP, непригоден для браузера». acquire() такой узел НЕ
-- исключает (голодание хуже — #2600/#2638, пул 4 узла), а
-- отправляет в КОНЕЦ очереди выдачи: его возьмут, только
-- если свободных пригодных нет.
-- browser_check_at — когда браузерную пробу гоняли последний раз. Такт у неё
-- свой, редкий (BROWSER_PROBE_MINUTES): она стоит запуска
-- camoufox (~8с замерено на проде), ipify — миллисекунды.
--
-- IDEMPOTENCY / SAFETY:
-- ADD COLUMN IF NOT EXISTS × 3, аддитивно, без backfill'а: NULL/0 = «браузерную
-- пробу ещё не гоняли», ровно то состояние, в котором пул и находится. Ни одна
-- существующая выборка не меняет результат (все три колонки новые). Повторный
-- прогон — no-op (auto-apply strict на деплое это требует).
--
-- Dependencies: 157_scrape_proxies.sql
BEGIN;
ALTER TABLE scrape_proxies
ADD COLUMN IF NOT EXISTS browser_fail_streak integer NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS browser_unfit_since timestamptz,
ADD COLUMN IF NOT EXISTS browser_check_at timestamptz;
COMMENT ON COLUMN scrape_proxies.browser_fail_streak IS
'Подряд-провалы браузерной пробы (сайдкар + camoufox через ЭТОТ узел), '
'атрибутированные узлу. НЕ обнуляется успешной ipify-пробой — иначе дешёвая '
'проба стирает вердикт дорогого тракта (#2723). Обнуляется успешной браузерной '
'пробой. Порог → browser_unfit_since, см. proxy_pool.BROWSER_UNFIT_THRESHOLD.';
COMMENT ON COLUMN scrape_proxies.browser_unfit_since IS
'NOT NULL = узел жив для обычного HTTP, но браузерный тракт через него не '
'работает (#2723). Это НЕ enabled=false: узел остаётся в пуле и обслуживает '
'curl-путь, а acquire() лишь отдаёт его последним. Полное выключение по-прежнему '
'значит «узел мёртв целиком» (серия транспортных сбоев) либо решение оператора.';
COMMENT ON COLUMN scrape_proxies.browser_check_at IS
'Последняя браузерная проба. Такт свой, редкий (proxy_pool.BROWSER_PROBE_MINUTES): '
'одна такая проба = запуск camoufox (~8с на проде), против миллисекунд у ipify. '
'На неподтверждённом провале НЕ обновляется — чтобы следующий же цикл '
'healthcheck подтвердил/опроверг отказ, а не ждал полный такт.';
COMMIT;