perf(tradein): снять блокировку event loop на POST /estimate (#2207) #2225

Merged
lekss361 merged 1 commit from fix/tradein-estimate-event-loop into main 2026-07-02 20:39:49 +00:00
Owner

Summary

  • async estimate_quality выпускал ~28 синхронных psycopg PostGIS-запросов прямо на event loop; прод — один uvicorn worker → одна медленная оценка (холодный кэш, wide-radius fallback) стопила все конкурентные запросы, включая /health.
  • 15 sync DB-кластеров обёрнуты в await asyncio.to_thread(...) (паттерн geocoder.py), строго последовательно — Session не используется конкурентно (никакого gather на DB-хелперах).
  • SAVEPOINT-блок (_backfill_house_fias) целиком внутри одного потока; INSERT + IMV-UPDATE + db.commit() сгруппированы атомарно в один to_thread (побочно улучшает атомарность persist-фазы).
  • Sync-сигнатуры внутренностей (_price_from_inputs, _fetch_analogs, _fetch_anchor_comps, _fetch_dkp_corridor, _fetch_house_imv_anchor) не тронуты — backtest-harness и frozen CI-регресс-гейт работают как раньше. Pricing-логика не изменена (перенос исполнения, не поведения).
  • Тест неблокирования: _fetch_analogstime.sleep(0.3), конкурентная лёгкая корутина завершается за <0.25s (при блокировке было бы ≥0.3).

Как проверено

  • Полный локальный pytest: 2960 passed, 6 skipped, 1 deselected (включая frozen backtest regression gate + fixture roundtrip).
  • ruff — чисто. code-reviewer: APPROVE (diff прочитан построчно, param-словари INSERT сверены 180=180, поведенческих расхождений нет).
  • Post-deploy план: 3-5 параллельных /estimate изнутри контейнера + /health остаётся отзывчивым.

Refs #2207

## Summary - `async estimate_quality` выпускал ~28 синхронных psycopg PostGIS-запросов прямо на event loop; прод — один uvicorn worker → одна медленная оценка (холодный кэш, wide-radius fallback) стопила все конкурентные запросы, включая `/health`. - 15 sync DB-кластеров обёрнуты в `await asyncio.to_thread(...)` (паттерн geocoder.py), строго последовательно — Session не используется конкурентно (никакого gather на DB-хелперах). - SAVEPOINT-блок (`_backfill_house_fias`) целиком внутри одного потока; INSERT + IMV-UPDATE + `db.commit()` сгруппированы атомарно в один to_thread (побочно улучшает атомарность persist-фазы). - Sync-сигнатуры внутренностей (`_price_from_inputs`, `_fetch_analogs`, `_fetch_anchor_comps`, `_fetch_dkp_corridor`, `_fetch_house_imv_anchor`) не тронуты — backtest-harness и frozen CI-регресс-гейт работают как раньше. Pricing-логика не изменена (перенос исполнения, не поведения). - Тест неблокирования: `_fetch_analogs` → `time.sleep(0.3)`, конкурентная лёгкая корутина завершается за <0.25s (при блокировке было бы ≥0.3). ## Как проверено - Полный локальный pytest: **2960 passed, 6 skipped, 1 deselected** (включая frozen backtest regression gate + fixture roundtrip). - ruff — чисто. code-reviewer: ✅ APPROVE (diff прочитан построчно, param-словари INSERT сверены 180=180, поведенческих расхождений нет). - Post-deploy план: 3-5 параллельных `/estimate` изнутри контейнера + `/health` остаётся отзывчивым. Refs #2207
lekss361 added 1 commit 2026-07-02 20:28:41 +00:00
perf(tradein): снять блокировку event loop на POST /estimate (#2207)
All checks were successful
CI Trade-In / backend-tests (pull_request) Successful in 1m36s
CI Trade-In / 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 / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
b71cba916d
async estimate_quality выпускал ~28 синхронных psycopg PostGIS-запросов
прямо на event loop; прод — один uvicorn worker → одна медленная оценка
(холодный кэш, wide-radius fallback) стопила ВСЕ конкурентные запросы,
включая /health (флап healthcheck).

- 15 sync DB-кластеров обёрнуты в await asyncio.to_thread (паттерн
  geocoder.py), строго последовательно — Session не используется конкурентно
- SAVEPOINT-блок (_backfill_house_fias) целиком внутри одного потока,
  транзакционные точки не сдвинуты; INSERT+IMV-UPDATE+commit сгруппированы
  атомарно в один to_thread
- sync-сигнатуры внутренностей (_price_from_inputs, _fetch_analogs, ...)
  не тронуты — backtest-harness и frozen regression gate зелёные
- тест неблокирования: sleep(0.3) в _fetch_analogs, конкурентная корутина
  завершается за <0.25s

Refs #2207
lekss361 merged commit 4ce0f51bb8 into main 2026-07-02 20:39:49 +00:00
lekss361 deleted branch fix/tradein-estimate-event-loop 2026-07-02 20:39:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2225
No description provided.