fix(gate): never block hub account on live balance fetch

Under RS alert ccxt contention, sync get_exchange_capitals made /api/hub/account time out. Return cache immediately and refresh in a background thread when force=False.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-11 12:38:25 +08:00
parent 772ba861e9
commit f086f57c91
+43 -6
View File
@@ -2834,13 +2834,13 @@ def friendly_exchange_error(err, available_usdt=None):
return f"交易所下单失败:{clean}"
def get_exchange_capitals(force=False):
ok_live, _ = ensure_exchange_live_ready()
if not ok_live:
return None, None
_BALANCE_REFRESH_LOCK = threading.Lock()
_BALANCE_REFRESH_INFLIGHT = False
def _fetch_exchange_capitals_sync():
"""同步拉取资金/交易账户余额并写入缓存(会占用 ccxt,勿在中控热路径直接调用)."""
now_ts = time.time()
if (not force) and ACCOUNT_BALANCE_CACHE["updated_at"] and now_ts - ACCOUNT_BALANCE_CACHE["updated_at"] < BALANCE_REFRESH_SECONDS:
return ACCOUNT_BALANCE_CACHE["funding_usdt"], ACCOUNT_BALANCE_CACHE["trading_usdt"]
try:
ACCOUNT_BALANCE_CACHE["funding_usdt"] = _fetch_gate_funding_usdt()
except Exception:
@@ -2854,6 +2854,43 @@ def get_exchange_capitals(force=False):
return ACCOUNT_BALANCE_CACHE["funding_usdt"], ACCOUNT_BALANCE_CACHE["trading_usdt"]
def _kick_exchange_capitals_refresh():
"""后台刷新余额;与 key_rs 争用时不阻塞看板/中控请求."""
global _BALANCE_REFRESH_INFLIGHT
with _BALANCE_REFRESH_LOCK:
if _BALANCE_REFRESH_INFLIGHT:
return
_BALANCE_REFRESH_INFLIGHT = True
def _worker():
global _BALANCE_REFRESH_INFLIGHT
try:
_fetch_exchange_capitals_sync()
except Exception:
pass
finally:
with _BALANCE_REFRESH_LOCK:
_BALANCE_REFRESH_INFLIGHT = False
threading.Thread(target=_worker, name="gate-balance-refresh", daemon=True).start()
def get_exchange_capitals(force=False):
ok_live, _ = ensure_exchange_live_ready()
if not ok_live:
return None, None
now_ts = time.time()
has_cache = bool(ACCOUNT_BALANCE_CACHE["updated_at"])
fresh = has_cache and (now_ts - ACCOUNT_BALANCE_CACHE["updated_at"] < BALANCE_REFRESH_SECONDS)
if (not force) and fresh:
return ACCOUNT_BALANCE_CACHE["funding_usdt"], ACCOUNT_BALANCE_CACHE["trading_usdt"]
if not force:
# 过期/冷缓存:先返回现有值(可空),后台刷新,避免 /api/hub/account 被 RS 监控拖死
_kick_exchange_capitals_refresh()
return ACCOUNT_BALANCE_CACHE["funding_usdt"], ACCOUNT_BALANCE_CACHE["trading_usdt"]
return _fetch_exchange_capitals_sync()
def execute_transfer_usdt(amount, from_account, to_account):
from lib.exchange.gate_transfer_lib import execute_transfer_usdt as _gate_execute_transfer_usdt