fix(tradein/proxy): один прокси на сессию браузера вместо смены на каждом запросе #2640

Merged
bot-backend merged 1 commit from fix/tradein-sticky-proxy-per-session into main 2026-08-04 18:45:38 +00:00

1 commit

Author SHA1 Message Date
bot-backend
5e247c6264 fix(tradein/proxy): один прокси на сессию браузера вместо смены на каждом запросе
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
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 2m40s
BrowserFetcher acquire/release-ил lease на КАЖДЫЙ /fetch. При росте пула с 1 до
3 узлов (id 9/10/11, affinity=any) acquire() стал гарантированно выдавать
ДРУГОЙ прокси на каждый запрос (ORDER BY last_ok_at NULLS LAST) — tradein-browser
релончит camoufox при любой смене желаемого прокси, теряя сессионные куки и
усиливая антибот-подозрительность (поток "первых визитов").

Теперь lease берётся один раз в __aenter__ на весь жизненный цикл BrowserFetcher
(целый прогон, часы) и отпускается один раз в __aexit__ (finally — не течёт при
исключении). Коллизия с reap_stale_leases (30 минут, а прогоны бывают часами):
не увеличивали порог (ослабило бы crash-recovery мёртвых run'ов), вместо этого
proxy_pool.touch() — heartbeat, продлевающий leased_at на каждый /fetch, пока
сессия жива; без heartbeat'а (упавший run) lease реапится как раньше. mark_health
остаётся на каждый /fetch (не огрублена до раза в сессию) + осознанная ротация
lease после 3 подряд неудач (не мечемся, как раньше).

Не трогали: acquire()-сортировку, curl-путь (providers/_proxy.py — сессии там и
так короткоживущие, per-request пересоздание не несёт cost релонча браузера),
run_id (только log-attribution, не требуется для фикса).
2026-08-04 23:39:38 +05:00