from __future__ import annotations from datetime import datetime from threading import Lock from typing import Any from backend.data.datahub.settings import DATASETS DATASET_LABELS = { "calendar": "交易日历", "stocks": "股票主档", "daily": "个股日K", "index_daily": "指数日K", "valuation": "估值", "moneyflow": "资金流", "auction": "竞价", "limit_events": "涨停池", "popularity": "人气榜", "dragon_tiger": "龙虎榜", "sector_daily": "题材板块", "quotes": "全市场实时行情", "index_quotes": "指数实时行情", "intraday": "分时", "status": "数据集状态", } class DatahubRouteLedger: def __init__(self) -> None: self._lock = Lock() self._rows: dict[str, dict[str, Any]] = {} def record(self, dataset: str, route: str, source: str = "", error: str = "") -> None: name = str(dataset or "").strip() or "unknown" with self._lock: self._rows[name] = { "dataset": name, "label": DATASET_LABELS.get(name, name), "route": "legacy" if route == "legacy" else "datahub", "source": str(source or "").strip(), "error": str(error or "").strip(), "at": datetime.now().astimezone().isoformat(timespec="seconds"), } def snapshot(self) -> list[dict[str, Any]]: with self._lock: rows = [dict(item) for item in self._rows.values()] order = {name: index for index, name in enumerate(DATASETS)} rows.sort(key=lambda item: (order.get(str(item.get("dataset")), 99), str(item.get("dataset")))) return rows def clear(self) -> None: with self._lock: self._rows.clear() LEDGER = DatahubRouteLedger()