feat(tradein/estimate): потолок одновременных оценок — 4 слота, быстрый 429 (#3082) #3097
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3097
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/3082-estimate-concurrency"
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?
Что
На
/trade-in/estimateне было ограничителя одновременности: рейт-лимит меряет частоту (300/60с вправе стартовать в одну секунду), квота — счётная и помесячная. Пила параллельных оценок (0.8–2.4с каждая, соединение общего пула + внешние тиры) выедала пул SQLAlchemy и тормозила весь/api/v1/*— детальный разбор в #3082.Как
asyncio.Semaphore(4)по образцуpublic/mera.py::_suggest_slots(там 4 слота на секундное автодополнение, мотив тот же):finallyсразу после дорогой части — инкремент квоты и сериализация ответа слот не держат.4+4 слота (estimate+suggest) = 8 одновременно удерживаемых соединений из 15 пула (5+10), остаток — прочим ручкам.
Согласование с #3083
Семафор живёт в памяти процесса: при переходе на несколько воркеров uvicorn фактический лимит умножится на их число. Комментарий об этом стоит прямо у семафора; #3083 начинать с замера, как её текст и требует.
Из чеклиста #3082 сознательно НЕ здесь
asyncio.gatherтрёх внешних вызовов (IMV/Yandex/Cian): все три делят один SQLAlchemySession, и часть работы уходит вasyncio.to_thread— параллелить без разбора всех трёх деревьев вызовов = ловушка session-poisoning (#2464). Отдельным коммитом после разбора.v1/geocode.suggest_addresses— «отдельным решением» по тексту задачи.Проверки
test_3082_estimate_concurrency_cap.py: 4 висящих оценки → 5-я получает быстрый 429 «занят» с Retry-After; после освобождения те же 4 завершаются 200 и следующий запрос проходит (release в finally). Красный на origin/main по ЗНАЧЕНИЮ (5-й прошёл с 200, 0×429) — не AttributeError: новые имена патчатся с raising=False.test_estimate_rate_limit.pyнетронут: 5 passed суммарно.Приёмка на проде: N параллельных POST — сверх 4 быстрые 429; p95 остальных ручек не растёт линейно от числа оценок.
🤖 Generated with Claude Code