perf(site-finder): air-quality TTL-кэш + neighbors_summary 2→1 SQL (#1130 Phase B) #1195
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
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#1195
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "perf/analyze-airquality-neighbors"
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?
Summary
Phase B продолжает hot-path latency cut'ы analyze_parcel поверх Phase A (PR #1194 уже в проде, дал 14.88s → 4.13s p50).
После Phase A профиль показал двух следующих guzzler'ов:
_fetch_air_quality_sync(0.26s в успешном hit + до 5s timeout на DNS-fail — тот же антипаттерн что был у weather) и_neighbors_summary(0.70s — два отдельных БД-запроса inline).Что делает PR
1. air-quality TTL-кэш — третий слот в
app/services/weather_cache.pyрядом с forecast/climate:get_air_quality_cached(lat, lon)— Open-Meteo Air Quality API (pm2_5/pm10/no2 текущего часа).threading.Lock._round_key/_now/_evict_one_if_full/_NEGATIVE_TTL_S._fetch_air_quality_syncудалена изparcels.py, импорт + вызов вanalyze_parcel(строка 1797) обновлён.2.
_neighbors_summary2 SQL → 1 statement:WITH neighbors AS (...), overlaps AS (...) SELECT COALESCE(json_agg(row_to_json(n)), '[]'::json), ...— один RTT.ST_DWithin(geom, point, 100m)для neighbors,ST_Intersects + ST_Areaдля overlaps, anti-fakes guards сохранены.Формат возвращаемых dict не меняется (frontend контракт).
Ожидаемый импакт
4.13s → ~3.4-3.6s p50 cache-hit (snap 0.26s air-cache + 0.05s neighbors merge + переменная weather/seasonal cache-hit). Если этого недостаточно — следующий guzzler
zone_regulation0.89s даже на DB cache-hit (Phase C, отдельный PR).Test plan
pytest tests/services/test_weather_cache.py -v→ 16 passed (11 forecast/climate + 5 новых air-cache).pytest -x tests/api/v1/→ 195 passed, 2 skipped, 0 failed.ruff check+ruff format --check→ clean.grep ':[a-z_]+::[a-z]'→ пусто (no psycopg v3 antipattern).66:41:0304011:1124черезdocker exec gendesign-backend-1 TestClient→ confirm p50 ≤ 3.6s (vs Phase A baseline 4.13s).Refs #1130