fix: 重启后立即读库展示持仓,CTP异步重连不再阻塞

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-25 14:57:39 +08:00
parent 01de8dfb69
commit 7daed9bd3a
5 changed files with 111 additions and 38 deletions
+28 -10
View File
@@ -6,7 +6,7 @@ import os
import threading
import time
from collections import deque
from typing import Any, Optional
from typing import Any, Callable, Optional
from locale_fix import ensure_process_locale
@@ -19,6 +19,23 @@ logger = logging.getLogger(__name__)
GATEWAY_NAME = "CTP"
_position_refresh_callback: Optional[Callable[[], None]] = None
def set_position_refresh_callback(fn: Optional[Callable[[], None]]) -> None:
global _position_refresh_callback
_position_refresh_callback = fn
def _fire_position_refresh_callback() -> None:
fn = _position_refresh_callback
if not fn:
return
try:
threading.Thread(target=fn, daemon=True, name="ctp-position-refresh").start()
except Exception as exc:
logger.debug("position refresh callback: %s", exc)
_bridge: Optional["CtpBridge"] = None
_bridge_lock = threading.Lock()
@@ -231,6 +248,7 @@ class CtpBridge:
self.refresh_positions()
except Exception as exc:
logger.debug("initial position query: %s", exc)
_fire_position_refresh_callback()
return
time.sleep(0.5)
finally:
@@ -796,7 +814,7 @@ class CtpBridge:
except Exception as exc:
logger.debug("refresh_positions: %s", exc)
def list_positions(self, *, refresh_if_empty: bool = True, refresh_margin: bool = True) -> list[dict[str, Any]]:
def list_positions(self, *, refresh_if_empty: bool = True, refresh_margin: bool = False) -> list[dict[str, Any]]:
if self._engine and self._connected_mode and refresh_margin:
self.refresh_positions()
out = self._collect_positions()
@@ -958,23 +976,23 @@ def ctp_start_connect(mode: str, *, force: bool = False) -> dict[str, Any]:
def ctp_try_auto_reconnect(mode: str) -> bool:
"""断线时静默重连;已连接且 ping 正常则直接返回 True。"""
"""断线时静默异步重连;已连接且 ping 正常则直接返回 True。"""
b = get_bridge()
if not b.available():
return False
if b.connect_in_progress():
return False
return True
st = _setting_for_mode(mode)
if not st.get("用户名") or not st.get("密码") or not st.get("交易服务器"):
return False
if b.connected_mode == mode and b.ping():
return True
try:
b.connect(mode, force=False)
return b.connected_mode == mode
except Exception as exc:
logger.info("CTP 自动重连失败: %s", exc)
return False
info = b.start_connect_async(mode, force=False)
return bool(
info.get("connected")
or info.get("connecting")
or info.get("started")
)
def ctp_status(mode: str) -> dict[str, Any]: