mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 18:04:16 +08:00
fix(config): v1.19.4 MAC客户端不再污染标准best_host(取不到数据根因)
根因:mac/client.py 的 MacClient.from_best_host 和 AsyncMacClient.from_best_host 调用 save_best_host(best),把选中的 MAC 协议服务器(如 121.36.248.138) 写进了全局 best_host 字段——但这个字段是标准 TDX 协议用的。之后标准 AsyncTdxClient 用 get_best_host 读到这个 MAC host,用标准协议请求 MAC 服务器,返回空 body(偏移 2 剩余 0)。web app lifespan 启动 MAC 客户端 时触发污染。 修复: - config.py 新增独立的 best_mac_host 字段 + get_best_mac_host / save_best_mac_host - mac/client.py 4 处改用新字段(不再碰 save_best_host / get_best_host) - get_best_host 加交叉污染校验:缓存 host 不在标准列表里自动重置 (自动修复已被污染的 config.json,用户无需手动操作) 测试:新增 5 个回归测试(污染检测 + MAC host 隔离),907 全过。
This commit is contained in:
+48
-2
@@ -160,12 +160,29 @@ def _save(data: dict[str, Any]) -> None:
|
||||
|
||||
|
||||
def get_best_host() -> str:
|
||||
"""返回当前最佳主机地址。优先级:环境变量 > config.json > 默认列表首个。"""
|
||||
"""返回当前最佳主机地址。优先级:环境变量 > config.json > 默认列表首个。
|
||||
|
||||
含交叉污染校验:历史上 ``MacClient.from_best_host`` 曾误调 ``save_best_host``
|
||||
把 MAC 服务器写入 ``best_host``(v1.19.3 "取不到行情" bug)。这里检测到
|
||||
缓存的 host 不在标准 host 候选列表里时,自动重置为默认首个,避免用错协议。
|
||||
"""
|
||||
env = os.environ.get("EASY_TDX_HOST")
|
||||
if env:
|
||||
return env
|
||||
cfg = _load()
|
||||
return cast(str, cfg.get("best_host", _FALLBACK_HOSTS[0]))
|
||||
cached = cast(str, cfg.get("best_host", _FALLBACK_HOSTS[0]))
|
||||
|
||||
# 交叉污染校验:cached 必须在标准 host 候选列表(known_hosts + 源码默认)里。
|
||||
# 如果是 MAC host(121.36.x.x 等),不在标准列表里 → 重置。
|
||||
all_std_hosts = set(cfg.get("known_hosts", [])) | set(_FALLBACK_HOSTS)
|
||||
if cached not in all_std_hosts:
|
||||
# 被污染了(MAC/ex host 混入),重置为默认首个并持久化
|
||||
cfg["best_host"] = _FALLBACK_HOSTS[0]
|
||||
cfg["best_host_updated_at"] = datetime.now(_SHANGHAI_TZ).isoformat()
|
||||
_save(cfg)
|
||||
return _FALLBACK_HOSTS[0]
|
||||
|
||||
return cached
|
||||
|
||||
|
||||
def get_known_hosts() -> list[str]:
|
||||
@@ -189,6 +206,20 @@ def get_mac_hosts() -> list[str]:
|
||||
return cast(list[str], cfg.get("mac_hosts", list(_FALLBACK_MAC_HOSTS)))
|
||||
|
||||
|
||||
def get_best_mac_host() -> str:
|
||||
"""返回当前最佳 MAC 协议主机。
|
||||
|
||||
与 ``get_best_host``(标准 TDX 协议)分开存:MAC 和标准协议用不同的
|
||||
服务器列表和协议格式,共用同一个字段会导致 MAC 客户端选出的 host
|
||||
被标准客户端误用,用标准协议请求 MAC 服务器返回空 body。
|
||||
"""
|
||||
env = os.environ.get("EASY_TDX_MAC_HOST")
|
||||
if env:
|
||||
return env
|
||||
cfg = _load()
|
||||
return cast(str, cfg.get("best_mac_host", _FALLBACK_MAC_HOSTS[0]))
|
||||
|
||||
|
||||
def get_ex_hosts() -> list[str]:
|
||||
"""返回扩展行情服务器列表。"""
|
||||
cfg = _load()
|
||||
@@ -282,3 +313,18 @@ def save_best_mac_ex_host(host: str) -> None:
|
||||
if "mac_ex_hosts" not in cfg:
|
||||
cfg["mac_ex_hosts"] = list(_FALLBACK_MAC_EX_HOSTS)
|
||||
_save(cfg)
|
||||
|
||||
|
||||
def save_best_mac_host(host: str) -> None:
|
||||
"""保存最佳 MAC 协议主机到配置文件(独立于标准 TDX 的 best_host)。
|
||||
|
||||
MAC 客户端必须用这个,不能复用 ``save_best_host``——否则选出的 MAC
|
||||
服务器会污染标准 TDX 协议的 ``best_host``,导致标准客户端用错协议请求
|
||||
MAC 服务器,返回空 body(v1.19.3 "取不到行情" bug 的根因)。
|
||||
"""
|
||||
cfg = _load()
|
||||
cfg["best_mac_host"] = host
|
||||
cfg["best_mac_host_updated_at"] = datetime.now(_SHANGHAI_TZ).isoformat()
|
||||
if "mac_hosts" not in cfg:
|
||||
cfg["mac_hosts"] = list(_FALLBACK_MAC_HOSTS)
|
||||
_save(cfg)
|
||||
|
||||
@@ -16,7 +16,13 @@ from .._df import _apply_bar_time_align_df, _period_to_minutes, _to_df
|
||||
from .._reconnect import _RETRY_DELAYS, AsyncHeartbeatMixin
|
||||
from ..codec.bitmap import Fields, PresetField
|
||||
from ..commands.base import BaseCommand
|
||||
from ..config import get_best_host, get_mac_hosts, get_port, get_timeout, save_best_host
|
||||
from ..config import (
|
||||
get_best_mac_host,
|
||||
get_mac_hosts,
|
||||
get_port,
|
||||
get_timeout,
|
||||
save_best_mac_host,
|
||||
)
|
||||
from ..exceptions import TdxConnectionError
|
||||
from ..transport.async_ import AsyncTdxConnection
|
||||
from ..transport.sync import TdxConnection, ping_mac_all
|
||||
@@ -147,7 +153,7 @@ class MacClient:
|
||||
auto_reconnect: bool = True,
|
||||
heartbeat_interval: float = 15.0,
|
||||
) -> None:
|
||||
self._host = host if host is not None else get_best_host()
|
||||
self._host = host if host is not None else get_best_mac_host()
|
||||
self._port = port if port is not None else get_port()
|
||||
self._timeout = timeout if timeout is not None else get_timeout()
|
||||
self._auto_reconnect = auto_reconnect
|
||||
@@ -180,7 +186,7 @@ class MacClient:
|
||||
timeout = get_timeout()
|
||||
ranked = ping_mac_all(hosts, port, ping_timeout)
|
||||
best = ranked[0][0] if ranked else hosts[0]
|
||||
save_best_host(best)
|
||||
save_best_mac_host(best)
|
||||
return cls(best, port, timeout, auto_reconnect, heartbeat_interval)
|
||||
|
||||
@staticmethod
|
||||
@@ -1156,7 +1162,7 @@ class AsyncMacClient(AsyncHeartbeatMixin):
|
||||
auto_reconnect: bool = True,
|
||||
heartbeat_interval: float = 15.0,
|
||||
) -> None:
|
||||
self._host = host if host is not None else get_best_host()
|
||||
self._host = host if host is not None else get_best_mac_host()
|
||||
self._port = port if port is not None else get_port()
|
||||
self._timeout = timeout if timeout is not None else get_timeout()
|
||||
self._auto_reconnect = auto_reconnect
|
||||
@@ -1191,7 +1197,7 @@ class AsyncMacClient(AsyncHeartbeatMixin):
|
||||
timeout = get_timeout()
|
||||
ranked = ping_mac_all(hosts, port, ping_timeout)
|
||||
best = ranked[0][0] if ranked else hosts[0]
|
||||
save_best_host(best)
|
||||
save_best_mac_host(best)
|
||||
return cls(best, port, timeout, auto_reconnect, heartbeat_interval)
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user