2 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 00bc07a55f |
fix(tradein/proxy): backup-узел должен быть пригоден + рычаг снятия бана (#2600 п.2)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 7s
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 2m45s
Правки по deep-review PR #2654. MEDIUM. Внутренний EXISTS считал backup'ом любой enabled-узел affinity. До п.2 это было эквивалентно «пригоден», потому что бан выключал узел глобально; теперь узел бывает enabled и одновременно забанен СВОИМ же источником. Fallback мог увести последний реально рабочий узел выделенной affinity (два domclick-узла, один забанен domclick'ом → второй уходит под avito → domclick без прокси). Добавлено требование, что backup не забанен своим источником — в acquire и зеркально в защите mark_banned. MEDIUM. У оператора не осталось способа снять бан: в п.1 ложное срабатывание лечилось PATCH enabled=true (он обнулял disabled_reason), теперь бан живёт в отдельной таблице и истекает только по таймеру, до 72ч при эскалации. Добавлен proxy_pool.clear_source_bans; зовётся из patch_proxy при ручном включении и после УСПЕШНОЙ ротации exit-IP (бан привязан к proxy_id, а банился IP — после смены адреса строка держала бы узел вне выдачи без причины). LOW. Тест защиты дублировал логику вместо её проверки: ban-предикаты в фейксессии теперь гейтятся по подстрокам боевого SQL (как в acquire-ветке) — проверено мутацией, тесты краснеют при удалении NOT EXISTS из запроса. LOW. Конверсия в миграции 210 матчила disabled_reason по LIKE 'banned:%' и могла отменить ручное выключение оператора (формат подсказан комментарием 209-й) — сужено до точного списка значений домена provider_affinity. LOW. Docstring report_ban в browser_fetcher описывал старую модель (enabled=false); формула в COMMENT ON COLUMN была на шаг мимо (срок ТЕКУЩЕГО бана, не следующего). Расхождение с acquire по leased_by зафиксировано в докстринге как осознанное. Refs #2600 |
|||
| 964867a943 |
feat(tradein/proxy): здоровье прокси по паре «узел × источник» (#2600 п.2)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 8s
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 2m43s
Бан площадкой был глобальным: п.1 на распознанный бан выключал узел целиком (enabled=false, disabled_reason='banned:<source>'). Реальность другая — Авито банит IP, а Яндекс через тот же IP ходит чисто, поэтому один забаненный источник выкидывал живой узел из пула для всех и худил пул быстрее, чем его пополняют (#2638). Плюс такое состояние не самолечилось: ipify площадку не эмулирует, бан не видит, а non-NULL disabled_reason блокирует авто-воскрешение (#2610) — нужен был ручной PATCH. Теперь бан — свойство ПАРЫ (proxy_id, source) в scrape_proxy_source_bans: acquire(source) не выдаёт узел только этому источнику, для остальных узел первосортный; снимается сам по времени. Срок эскалирует 6ч → 12 → 24 → 48 → 72 (потолок) на повторных банах той же пары; ban_count сбрасывается purge'ем истёкших строк через 7 суток — поэтому purge намеренно отложенный, а не по banned_until < now(). Защита последнего узла сохранена, но считается по источнику: если после бана у acquire(source) не останется кандидатов — бан не пишется, WARNING зовёт пополнять пул. Миграция 210 конвертирует прод-остатки п.1 (enabled=false + disabled_reason LIKE 'banned:%') в 6-часовые per-source баны и возвращает узлы в строй — иначе они висели бы выключенными вечно. Оператору активные баны видны в GET/PATCH /admin/proxies (source_bans) — без этого «узел включён, но не выдаётся» необъяснимо. Refs #2600 |