From 7443383720595417be637c4fd04173fb94558542 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Mon, 15 Jun 2026 20:08:13 +0800 Subject: [PATCH] Avoid raw runway history rebuild on hot path --- tests/test_latest_observation_overlay.py | 47 ++++++++++++++++++++++ web/services/latest_observation_overlay.py | 11 ++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/test_latest_observation_overlay.py b/tests/test_latest_observation_overlay.py index 5cae3e05..6b8f4890 100644 --- a/tests/test_latest_observation_overlay.py +++ b/tests/test_latest_observation_overlay.py @@ -161,6 +161,53 @@ def test_overlay_builds_amsc_runway_history_from_raw_store(): ] +def test_overlay_skips_raw_store_when_runway_history_already_has_points(): + class FakeDB: + def get_latest_raw_observation(self, source, city): + assert (source, city) == ("amsc_awos", "chengdu") + return { + "observed_at": "2026-06-15T11:08:00+00:00", + "station_code": "ZUUU", + "payload": { + "source": "amsc_awos", + "icao": "ZUUU", + "temp_c": 25.4, + "observation_time": "2026-06-15T11:08:00+00:00", + "runway_obs": { + "point_temperatures": [ + { + "runway": "02L/20R", + "target_runway_max": 25.4, + }, + ], + }, + }, + } + + def list_raw_observation_history(self, source, city, *, minutes=60, limit=1000): + raise AssertionError("raw store history should not be read for populated runway history") + + result = overlay_latest_amsc_observation( + FakeDB(), + "chengdu", + { + "name": "chengdu", + "temp_symbol": "°C", + "runway_plate_history": { + "02L/20R": [ + {"time": "2026-06-15T11:04:00+00:00", "temp": 25.6}, + {"time": "2026-06-15T11:06:00+00:00", "temp": 25.5}, + ], + }, + }, + ) + + assert result["runway_plate_history"]["02L/20R"][-1] == { + "time": "2026-06-15T11:08:00+00:00", + "temp": 25.4, + } + + def test_overlay_uses_latest_success_when_newer_status_row_has_no_observation(): class FakeDB: def get_latest_raw_observation(self, source, city): diff --git a/web/services/latest_observation_overlay.py b/web/services/latest_observation_overlay.py index 57b4461b..86dd8738 100644 --- a/web/services/latest_observation_overlay.py +++ b/web/services/latest_observation_overlay.py @@ -313,6 +313,16 @@ def _append_amsc_runway_history_from_raw_store( city: str, payload: dict[str, Any], ) -> bool: + existing_history = payload.get("runway_plate_history") + if isinstance(existing_history, dict): + existing_points = [ + len(points) + for points in existing_history.values() + if isinstance(points, list) + ] + if max(existing_points or [0]) > 1: + return False + lister = getattr(db, "list_raw_observation_history", None) if not callable(lister): return False @@ -321,7 +331,6 @@ def _append_amsc_runway_history_from_raw_store( except Exception as exc: logger.debug("latest AMSC raw history overlay skipped city={}: {}", city, exc) return False - existing_history = payload.get("runway_plate_history") payload["runway_plate_history"] = deepcopy(existing_history) if isinstance(existing_history, dict) else {} changed = False for row in rows if isinstance(rows, list) else []: