HOTFIX web: /status/full 500 (str→tzinfo), /plan/compare 500 (chybějící comparison), canonical PV fn 4.5s→0.4s (force_custom_plan)
All checks were successful
CI and deploy / migration-check (push) Successful in 19s
CI and deploy / deploy (push) Successful in 1m17s

1) full_status._iso_utc dostával z JSONB bundle stringy → AttributeError → 500
   celého /status/full; nyní parsuje přes _parse_ts.
2) /plan/compare: NameError — 'comparison = _bundle_from_current(compare_raw)'
   se nikdy nesestavilo (smazaný řádek), endpoint vždy 500.
3) fn_forecast_pv_slots_range_canonical_ab: PG 18 cachuje plány SQL funkcí →
   generický plán 4.5 s / 607k buffers; set plan_cache_mode=force_custom_plan
   → 0.4 s / 34k (změřeno explain analyze na živé DB). Táhne /plan/current,
   /plan/compare i rolling plánovač.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dusan Vojacek
2026-06-12 15:48:10 +02:00
parent dd3bd55c0e
commit 62a5c64f77
3 changed files with 8 additions and 1 deletions

View File

@@ -40,7 +40,10 @@ HEARTBEAT_STALE_SEC = 300
EXPECTED_TOMORROW_PRICE_SLOTS = 90 EXPECTED_TOMORROW_PRICE_SLOTS = 90
def _iso_utc(dt: datetime | None) -> str | None: def _iso_utc(dt: datetime | str | None) -> str | None:
# JSONB bundle z fn_site_full_status nese timestampy jako stringy — parsovat,
# jinak .tzinfo na str = AttributeError → 500 celého /status/full.
dt = _parse_ts(dt)
if dt is None: if dt is None:
return None return None
if dt.tzinfo is None: if dt.tzinfo is None:

View File

@@ -207,6 +207,7 @@ async def get_plan_compare(
raise HTTPException(status_code=404, detail="No comparison plan") raise HTTPException(status_code=404, detail="No comparison plan")
active = _bundle_from_current(active_raw) active = _bundle_from_current(active_raw)
comparison = _bundle_from_current(compare_raw)
diff, slot_diffs = _build_plan_diff(active, comparison) diff, slot_diffs = _build_plan_diff(active, comparison)
return PlanningCompareResponseModel( return PlanningCompareResponseModel(
active=active, active=active,

View File

@@ -28,6 +28,9 @@ returns jsonb
language sql language sql
stable stable
set work_mem = '64MB' set work_mem = '64MB'
-- PG 18 cachuje plány SQL funkcí → generický plán bez znalosti hodnot parametrů
-- (4.5 s / 607k buffers); s custom planem dle skutečných hodnot 0.4 s / 34k.
set plan_cache_mode = force_custom_plan
as $fn$ as $fn$
with tz as ( with tz as (
select coalesce(nullif(trim(s.timezone), ''), 'Europe/Prague') as tz_name select coalesce(nullif(trim(s.timezone), ''), 'Europe/Prague') as tz_name