Stop collector from triggering full weather refreshes

This commit is contained in:
2569718930@qq.com
2026-06-14 18:44:49 +08:00
parent 3e1e06d8e1
commit ccc8866229
9 changed files with 180 additions and 179 deletions
+74 -5
View File
@@ -2,6 +2,7 @@ from concurrent.futures import ThreadPoolExecutor, TimeoutError
import sqlite3
import threading
import time
from types import SimpleNamespace
def test_observation_source_gate_shares_inflight_and_cooldown(monkeypatch):
@@ -93,14 +94,13 @@ def test_observation_collector_profiles_match_source_cadence():
assert SOURCE_CADENCE_SECONDS["amsc_awos"] == 180
def test_observation_collector_run_due_once_refreshes_panel_cache():
def test_observation_collector_run_due_once_collects_without_panel_cache_refresh():
from web.observation_collector_service import (
ObservationCollector,
ObservationSourceProfile,
)
calls = []
refreshed = []
class FakeWeather:
def _uses_fahrenheit(self, city):
@@ -119,20 +119,17 @@ def test_observation_collector_run_due_once_refreshes_panel_cache():
interval_sec=180,
)
],
cache_refresher=lambda city: refreshed.append(city),
async_cache_refresh=False,
)
assert collector.run_due_once(now_ts=1000.0) == 1
assert calls == [("qingdao", False)]
assert refreshed == ["qingdao"]
assert collector.run_due_once(now_ts=1100.0) == 0
assert calls == [("qingdao", False)]
assert collector.run_due_once(now_ts=1180.0) == 1
assert calls == [("qingdao", False), ("qingdao", False)]
assert refreshed == ["qingdao", "qingdao"]
def test_raw_observation_store_records_latest_observation(tmp_path):
@@ -257,6 +254,46 @@ def test_observation_collector_writes_raw_observation_store(tmp_path):
assert latest["station_code"] == "ZSQD"
def test_observation_collector_writes_canonical_latest_from_source(tmp_path):
from src.database.db_manager import DBManager
from web.observation_collector_service import (
ObservationCollector,
ObservationSourceProfile,
)
db = DBManager(str(tmp_path / "polyweather.db"))
class FakeWeather:
def _uses_fahrenheit(self, city):
return False
def _attach_china_amsc_awos_data(self, results, city, use_fahrenheit):
results["amos"] = {
"source": "amsc_awos",
"source_label": "AMSC AWOS",
"temp_c": 24.0,
"observation_time": "2026-06-14T01:00:00+00:00",
"icao": "ZSQD",
"station_label": "Qingdao Jiaodong",
}
collector = ObservationCollector(
weather=FakeWeather(),
profiles=[ObservationSourceProfile("amsc_awos", ("qingdao",), 180)],
observation_store=db,
async_cache_refresh=False,
)
assert collector.run_due_once(now_ts=1000.0) == 1
canonical = db.get_canonical_temperature("qingdao")
assert canonical is not None
assert canonical["payload"]["value"] == 24.0
assert canonical["payload"]["source"] == "amsc_awos"
assert canonical["payload"]["source_role"] == "settlement_proxy"
assert canonical["payload"]["observed_at"] == "2026-06-14T01:00:00+00:00"
def test_observation_collector_consumes_refresh_request_queue(tmp_path):
from src.database.db_manager import DBManager
from web.observation_collector_service import (
@@ -486,6 +523,38 @@ def test_observation_collector_worker_entrypoint_exists():
assert callable(observation_collector_worker.main)
def test_observation_collector_worker_does_not_bind_panel_cache_refresher(monkeypatch):
from web import observation_collector_worker
captured = {}
def fake_start_observation_collector_loop(**kwargs):
captured.update(kwargs)
return SimpleNamespace(name="observation-collector")
class StopEvent:
@staticmethod
def wait(_timeout):
return True
@staticmethod
def set():
return None
monkeypatch.setattr(observation_collector_worker.signal, "signal", lambda *_args, **_kwargs: None)
monkeypatch.setattr(
observation_collector_worker,
"start_observation_collector_loop",
fake_start_observation_collector_loop,
)
monkeypatch.setattr(observation_collector_worker, "_STOP_EVENT", StopEvent())
observation_collector_worker.main()
assert captured["weather"] is observation_collector_worker._weather
assert captured.get("cache_refresher") is None
def test_ephemeral_observation_log_writes_skip_sqlite_lock(monkeypatch, tmp_path):
from src.database.db_manager import DBManager