fix(tradein/domclick): каждый запрос получал чистый браузерный контекст, куки реплеились протухшими (#3190) #3193
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3193
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/3118-domclick-warm-context"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Закрывает корневую причину из #3190. Refs #3118.
Что было
domclick_detail_backfillдве недели подряд давалattempted=4, enriched=1, blocked=3и статусbanned. Выглядело как «площадка нас забанила», оказалось иначе.Сайдкар на каждый
/fetchделаетpage = await browser.new_page()поверхAsyncCamoufox._browsers[provider]— это Browser, а не персистентный контекст, значит каждый запрос получал новый изолированный контекст, и cookie-jar умирал сразу после ответа. Туда вливался замороженный снимок кук изdomclick_session_cookies, в котором лежитqrator_jsid2— токен со сроком жизни ~2.5 часа, хранящийся у нас 30 дней.Первый запрос после заливки кук проходил с ещё живым токеном. Площадка выдавала новый через
Set-Cookie, мы его выбрасывали вместе с контекстом и на втором запросе показывали тот же протухший. QRATOR отвечал челлендж-страницей без__SSR_STATE__.Замеры на проде, 28.08
Свежий аккаунт залит, сессия валидна, куки доезжают до боевого пути (
last_used_atсовпадает с моментом старта прогона).item_id,year_built, история ценыСвежий exit-IP блокируется мгновенно — репутация адреса ни при чём. Тёплый контекст на тех же карточках проходит полностью.
Что сделано
browser.new_context(). Куки вливаются только при создании контекста, дальше jar живёт сам. Страница закрывается после ответа, контекст остаётся._close_browser, поэтому crash-relaunch, recycle-relaunch и shutdown его не теряют — висящих контекстов у мёртвого браузера не остаётся.reuse_context=False(дефолт) payload/fetchне получает новых ключей вовсе — поведение остальных трёх поставщиков не меняется ни на байт.BrowserFetcher.request_context_reset(). Понадобился потому, чтоfetch_detail()в kit не прокидываетreset_context, а менять этот промежуточный слой ради одного поставщика в рамках фикса не хотелось.⚠️ Порядок деплоя
Правка работает, только если
tradein-browserпересобран вместе с бэкендом. Старый сайдкар новых полей не знает: не упадёт, но и не починит ничего — продолжит делатьnew_page()на каждый запрос. Если после мержа метрика не сдвинулась, первым делом проверять, что контейнер браузера действительно пересоздан.Проверки
tradein-mvp/browser/— 137 тестов зелёные, включая новыйtest_server_reuse_context.py(8 тестов: контекст создаётся один раз на несколько фетчей, куки вливаются только при создании,reset_contextвыбрасывает старый, приreuse_context=Falseповедение прежнее,_close_browserзакрывает контекст).test_3118_domclick_warm_context.py— 7 тестов: оркестратор зовёт сброс ровно раз на блок; отложенный флаг потребляется ровно одним следующимfetch(); переживает transport-retry; при выключенном флаге payload чист.tests/tasks/test_domclick_detail_backfill.py— 10 тестов зелёные.Ревью пройдено (⚠️ minor, блокеров нет), оба замечания закрыты в этой же ветке: дублирование сброса на retry явно задокументировано как осознанная идемпотентность, и добавлены три теста на саму логику флага в
BrowserFetcher— раньше она не исполнялась ни одним тестом.Приёмка после деплоя
База:
enriched0-2 за прогон,blocked=3, статусbanned— четырнадцать прогонов подряд. Успех —enrichedзаметно больше при том жеblocked, в идеале прогон доходит до конца бюджета вместо остановки по третьему блоку. В очереди 1796 активных объявлений без обогащения, так что материала для замера достаточно.