fix(tradein/proxy): узел, зарезервированный за Домкликом, до Домклика не доходит (#2800 A) (#2802)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
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 3m6s
Deploy Trade-In / build-backend (push) Successful in 1m3s
Deploy Trade-In / deploy (push) Successful in 6m36s
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
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 3m6s
Deploy Trade-In / build-backend (push) Successful in 1m3s
Deploy Trade-In / deploy (push) Successful in 6m36s
This commit is contained in:
parent
f45ce3be2d
commit
7cd8c63b89
2 changed files with 67 additions and 8 deletions
|
|
@ -228,14 +228,21 @@ def acquire(db: Session, provider: str, *, run_id: int | None = None) -> ProxyLe
|
|||
чужая — только запасной вариант, чтобы источник не голодал при живых свободных узлах
|
||||
чужой affinity (#2600).
|
||||
|
||||
Fallback НЕ трогает последний enabled-узел выделенной (не-'any') affinity — см.
|
||||
173_scrape_proxies_add_domclick_affinity.sql: у domclick ровно один узел (id=1),
|
||||
намеренно вырезанный из общего пула, потому что QRATOR банит все прокси кроме этого
|
||||
одного чистого residential-адреса. Если fallback заберёт его под avito/cian/yandex,
|
||||
domclick останется без прокси вообще — хуже, чем голодание исходного источника,
|
||||
которое фикс призван устранить. Кандидат участвует в fallback, только если его
|
||||
affinity='any' ИЛИ у этой affinity есть ДРУГОЙ enabled-узел (EXISTS-подзапрос) —
|
||||
т.е. выдача не обнулит доступность выделенной affinity целиком.
|
||||
Fallback НЕ трогает последний enabled-узел выделенной (не-'any') affinity: если
|
||||
fallback заберёт его под чужой источник, «свой» останется без прокси вообще — хуже,
|
||||
чем голодание исходного источника, которое фикс призван устранить. Кандидат
|
||||
участвует в fallback, только если его affinity='any' ИЛИ у этой affinity есть ДРУГОЙ
|
||||
enabled-узел (EXISTS-подзапрос) — т.е. выдача не обнулит доступность выделенной
|
||||
affinity целиком.
|
||||
|
||||
Исторический повод для этой защиты (173_scrape_proxies_add_domclick_affinity.sql —
|
||||
единственный residential-узел id=1, закреплённый за domclick, потому что QRATOR
|
||||
банил остальные) снят миграцией 253 (#2800): живая проба показала, что как раз до
|
||||
рабочего хоста Домклика (bff-search-web.domclick.ru) этот узел НЕ доходит, а
|
||||
Авито/Яндекс через него работают — резервация держала узел за источником, которому
|
||||
он не годен, и прятала от тех, кому годен. Узлов с выделенной affinity на проде
|
||||
сейчас нет, но САМА защита остаётся: значение 'domclick' допустимо констрейнтом, и
|
||||
следующий выделенный узел должен получить её сразу, а не после повторного разбора.
|
||||
|
||||
ОБА запроса отсекают узлы с АКТИВНЫМ баном по ЭТОМУ provider'у
|
||||
(scrape_proxy_source_bans.banned_until > now(), #2600 п.2) — узел, забаненный Авито,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
-- 253_scrape_proxy_domclick_affinity_release.sql
|
||||
-- Снять с узла резервацию provider_affinity='domclick' (#2800).
|
||||
--
|
||||
-- WHY (замер, не рассуждение — живая проба 09.08.2026, тракт сайдкар+camoufox,
|
||||
-- POST /fetch на robots.txt рабочего хоста каждой площадки):
|
||||
--
|
||||
-- узел | affinity | avito | ekb.cian.ru | realty.yandex.ru | bff-search-web.domclick.ru
|
||||
-- -----+----------+-------+--------------------+------------------+---------------------------
|
||||
-- 1 | domclick | 200 | 200 «Ошибка — Циан»| 200 | 500 NS_ERROR_PROXY_BAD_GATEWAY
|
||||
-- 9 | any | 200 | 200 | 200 | 200
|
||||
-- 10 | any | 200 | 200 | 200 | 200
|
||||
-- 11 | any | 200 | 200 | 200 | 200
|
||||
--
|
||||
-- Узел, закреплённый 173-й миграцией СПЕЦИАЛЬНО за Домкликом, до рабочего хоста
|
||||
-- Домклика не доходит вообще (NS_ERROR_PROXY_BAD_GATEWAY на bff-search-web —
|
||||
-- именно туда ходит боевой сбор, см. providers/domclick/serp.py::_BFF_BASE), при
|
||||
-- этом Авито и Яндекс через него отвечают штатно. Резервация даёт ровно обратный
|
||||
-- эффект задуманному: единственный источник, которому узел ГОДЕН НЕ БЫЛ, держал его
|
||||
-- за собой, а два источника, которым он годен, его не видели —
|
||||
-- acquire('avito'|'yandex') отбирает по provider_affinity IN (source,'any'), а
|
||||
-- fallback этот узел не берёт (защита последнего узла выделенной affinity).
|
||||
--
|
||||
-- 'any', а НЕ enabled=false: узел жив для двух площадок из четырёх, выключать его
|
||||
-- целиком — терять четверть и без того дефицитного пула (#2638).
|
||||
--
|
||||
-- WHAT:
|
||||
-- provider_affinity='domclick' → 'any' для узлов, у которых affinity именно такая.
|
||||
-- CHECK-констрейнт (173) не трогаем: значение 'domclick' остаётся допустимым, если
|
||||
-- в пуле появится узел, который до Домклика реально доходит.
|
||||
--
|
||||
-- ЧТО ЭТА МИГРАЦИЯ НЕ ДЕЛАЕТ (граница честная):
|
||||
-- Она НЕ чинит Домклик. acquire('domclick') и до неё видел все четыре узла
|
||||
-- (affinity IN ('domclick','any')), т.е. шанс вытянуть узел 1 и потратить первый
|
||||
-- бакет впустую был и остаётся 1/4 — закрывает это проба по паре «узел × источник»
|
||||
-- (#2800 часть B), а не смена affinity. Здесь снимается только резервация.
|
||||
--
|
||||
-- IDEMPOTENCY / SAFETY:
|
||||
-- Один UPDATE в транзакции; повторный прогон не находит строк (no-op) — auto-apply
|
||||
-- strict на деплое это требует. Блокирующего DDL нет (см.
|
||||
-- scripts/check-migration-lock-timeout.py: правило про ALTER/DROP/CREATE INDEX),
|
||||
-- UPDATE берёт row-lock на единичные строки.
|
||||
--
|
||||
-- Dependencies: 157_scrape_proxies.sql, 173_scrape_proxies_add_domclick_affinity.sql
|
||||
|
||||
BEGIN;
|
||||
|
||||
UPDATE scrape_proxies
|
||||
SET provider_affinity = 'any',
|
||||
updated_at = now()
|
||||
WHERE provider_affinity = 'domclick';
|
||||
|
||||
COMMIT;
|
||||
Loading…
Add table
Reference in a new issue