-- 158_seed_proxy_healthcheck_schedule.sql -- Scheduler seed for the proxy-pool health-checker (#2162). АДДИТИВНО. -- -- WHAT (source='proxy_healthcheck'): -- trigger_proxy_healthcheck_run (scheduler.py) → run_proxy_healthcheck -- (services/proxy_pool.py): -- 1. reap_stale_leases — освобождает lease'ы старше STALE_LEASE_MINUTES (упавший -- sweep не вызвал release), иначе прокси навсегда «занят» мёртвым run'ом. -- 2. для каждого enabled-прокси гоняет ipify-пробу ЧЕРЕЗ сам прокси и пишет -- результат через mark_health: успех → consecutive_fails=0 + свежий exit_ip/ -- latency; фейл → consecutive_fails += 1, авто-disable при DISABLE_THRESHOLD. -- Чистый health-refresh пула — НЕ трогает боевые скрейперы (pick/lease/rotate из -- пула вместо env — отдельные шаги P3/P4). -- -- КАДЕНС (sub-hourly, не суточный): -- Штатный scheduler-каденс суточный (compute_next_run_at пикает next_run_at в окне -- [window_start_hour, window_end_hour) на interval_days суток вперёд). Health-check -- хочется чаще, поэтому trigger_proxy_healthcheck_run СРАЗУ после claim переопределяет -- next_run_at на now() + interval_minutes (default 30) — source-специфичный re-schedule, -- не трогая shared compute_next_run_at. window_start/end_hour для этого source не важны -- (next_run_at выставляется напрямую), но CHECK 0-23 требует валидных значений → 0..23 -- = «в любой час». next_run_at при сиде = now() → первый health-check вскоре после -- деплоя (в пределах SCHEDULER_TICK_SEC). -- -- default_params: -- interval_minutes -- 30: период между health-check'ами (trigger читает это). -- -- *** enabled=true — БЕЗОПАСНО *** -- Пул scrape_proxies по умолчанию ПУСТ (прокси грузятся оператором через admin-ручку -- POST /api/v1/admin/proxies/bulk). Пустой пул → run_proxy_healthcheck просто ничего не -- проверяет (checked=0), deploy нейтрален. Как только оператор зальёт прокси — -- health-check начнёт их пинговать. Внешние вызовы идут ТОЛЬКО на ipify через сами -- прокси (не на боевые площадки), анти-бот-рисков нет. -- -- DEPENDENCIES: 052_scrape_schedules.sql (table + UNIQUE(source)), -- 157_scrape_proxies.sql (пул, который проверяем). -- Idempotent: ON CONFLICT (source) DO NOTHING. -- Runner applies migrations WITHOUT --single-transaction, so wrap in explicit BEGIN/COMMIT. BEGIN; INSERT INTO scrape_schedules ( source, enabled, window_start_hour, window_end_hour, next_run_at, default_params ) VALUES ( 'proxy_healthcheck', true, 0, 23, now(), '{"interval_minutes": 30}'::jsonb ) ON CONFLICT (source) DO NOTHING; COMMIT;