功能:完善加氢站导航详情与缓存刷新

This commit is contained in:
lingniu
2026-09-02 14:05:49 +08:00
parent e7ee8583aa
commit a26179c8fe
5 changed files with 151 additions and 17 deletions
+48 -6
View File
@@ -31,6 +31,8 @@ STATION_CACHE_SECONDS = int(os.getenv("STATION_NAVIGATION_CACHE_SECONDS", "120")
VEHICLE_MAP_INTERNAL_BASE_URL = os.getenv("VEHICLE_MAP_INTERNAL_BASE_URL", "http://127.0.0.1:20800").rstrip("/")
_cache_lock = threading.Lock()
_cache = {}
_cache_load_locks = {}
_cache_refreshing = set()
def _static_asset_version():
@@ -80,16 +82,51 @@ def _post_open_platform(path, body):
return payload.get("data") or []
def _refresh_cached_value(key, loader):
try:
value = loader()
except Exception as exc:
print("{} cache background refresh deferred: {}".format(key, exc))
else:
with _cache_lock:
_cache[key] = (time.time(), value)
finally:
with _cache_lock:
_cache_refreshing.discard(key)
def _start_cache_refresh(key, loader):
threading.Thread(target=_refresh_cached_value, args=(key, loader), daemon=True).start()
def _cached(key, ttl_seconds, loader):
now = time.time()
refresh_in_background = False
with _cache_lock:
cached = _cache.get(key)
if cached and now - cached[0] < ttl_seconds:
return cached[1]
value = loader()
with _cache_lock:
_cache[key] = (now, value)
return value
if cached:
if key not in _cache_refreshing:
_cache_refreshing.add(key)
refresh_in_background = True
stale_value = cached[1]
else:
stale_value = None
load_lock = _cache_load_locks.setdefault(key, threading.Lock())
if cached:
if refresh_in_background:
_start_cache_refresh(key, loader)
return stale_value
with load_lock:
with _cache_lock:
cached = _cache.get(key)
if cached:
return _cached(key, ttl_seconds, loader)
value = loader()
with _cache_lock:
_cache[key] = (time.time(), value)
return value
def _load_station_directory():
@@ -137,7 +174,7 @@ class StationNavigationHandler(SimpleHTTPRequestHandler):
return
if path == "/api/stations":
try:
self._write_json(200, _cached("station-directory", STATION_CACHE_SECONDS, _load_station_directory))
payload = _cached("station-directory", STATION_CACHE_SECONDS, _load_station_directory)
except Exception as exc:
self.log_error("station directory refresh failed: %s", exc)
self._write_json(502, {
@@ -145,6 +182,8 @@ class StationNavigationHandler(SimpleHTTPRequestHandler):
"code": "UPSTREAM_UNAVAILABLE",
"message": "加氢站数据暂时不可用,请稍后重试",
})
return
self._write_json(200, payload)
return
if path == "/assets/logo_light.svg":
self._serve_logo()
@@ -213,7 +252,10 @@ class StationNavigationHandler(SimpleHTTPRequestHandler):
self.send_header("Cache-Control", "no-store")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
try:
self.wfile.write(body)
except (BrokenPipeError, ConnectionResetError):
self.log_message("client disconnected before JSON response completed")
if __name__ == "__main__":