fix: split rate/stats refresh intervals, rates 2s stats 2min

This commit is contained in:
root 2026-02-26 13:57:39 +00:00
parent 42e329cc55
commit 03218dce04
2 changed files with 21 additions and 10 deletions

View File

@ -15,6 +15,7 @@ app.add_middleware(
BINANCE_FAPI = "https://fapi.binance.com/fapi/v1" BINANCE_FAPI = "https://fapi.binance.com/fapi/v1"
SYMBOLS = ["BTCUSDT", "ETHUSDT"] SYMBOLS = ["BTCUSDT", "ETHUSDT"]
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
# 简单内存缓存history/stats 60秒rates 3秒 # 简单内存缓存history/stats 60秒rates 3秒
_cache: dict = {} _cache: dict = {}
@ -38,7 +39,7 @@ async def health():
async def get_rates(): async def get_rates():
cached = get_cache("rates", 3) cached = get_cache("rates", 3)
if cached: return cached if cached: return cached
async with httpx.AsyncClient(timeout=10) as client: async with httpx.AsyncClient(timeout=10, headers=HEADERS) as client:
tasks = [client.get(f"{BINANCE_FAPI}/premiumIndex", params={"symbol": s}) for s in SYMBOLS] tasks = [client.get(f"{BINANCE_FAPI}/premiumIndex", params={"symbol": s}) for s in SYMBOLS]
responses = await asyncio.gather(*tasks) responses = await asyncio.gather(*tasks)
result = {} result = {}
@ -65,7 +66,7 @@ async def get_history():
if cached: return cached if cached: return cached
end_time = int(datetime.utcnow().timestamp() * 1000) end_time = int(datetime.utcnow().timestamp() * 1000)
start_time = int((datetime.utcnow() - timedelta(days=7)).timestamp() * 1000) start_time = int((datetime.utcnow() - timedelta(days=7)).timestamp() * 1000)
async with httpx.AsyncClient(timeout=15) as client: async with httpx.AsyncClient(timeout=15, headers=HEADERS) as client:
tasks = [ tasks = [
client.get(f"{BINANCE_FAPI}/fundingRate", client.get(f"{BINANCE_FAPI}/fundingRate",
params={"symbol": s, "startTime": start_time, "endTime": end_time, "limit": 1000}) params={"symbol": s, "startTime": start_time, "endTime": end_time, "limit": 1000})
@ -92,7 +93,7 @@ async def get_stats():
if cached: return cached if cached: return cached
end_time = int(datetime.utcnow().timestamp() * 1000) end_time = int(datetime.utcnow().timestamp() * 1000)
start_time = int((datetime.utcnow() - timedelta(days=7)).timestamp() * 1000) start_time = int((datetime.utcnow() - timedelta(days=7)).timestamp() * 1000)
async with httpx.AsyncClient(timeout=15) as client: async with httpx.AsyncClient(timeout=15, headers=HEADERS) as client:
tasks = [ tasks = [
client.get(f"{BINANCE_FAPI}/fundingRate", client.get(f"{BINANCE_FAPI}/fundingRate",
params={"symbol": s, "startTime": start_time, "endTime": end_time, "limit": 1000}) params={"symbol": s, "startTime": start_time, "endTime": end_time, "limit": 1000})

View File

@ -13,12 +13,10 @@ export default function Dashboard() {
const [status, setStatus] = useState<"loading" | "running" | "error">("loading"); const [status, setStatus] = useState<"loading" | "running" | "error">("loading");
const [lastUpdate, setLastUpdate] = useState<string>(""); const [lastUpdate, setLastUpdate] = useState<string>("");
const fetchAll = useCallback(async () => { const fetchRates = useCallback(async () => {
try { try {
const [r, s, h] = await Promise.all([api.rates(), api.stats(), api.history()]); const r = await api.rates();
setRates(r); setRates(r);
setStats(s);
setHistory(h);
setStatus("running"); setStatus("running");
setLastUpdate(new Date().toLocaleTimeString("zh-CN")); setLastUpdate(new Date().toLocaleTimeString("zh-CN"));
} catch { } catch {
@ -26,11 +24,23 @@ export default function Dashboard() {
} }
}, []); }, []);
const fetchAll = useCallback(async () => {
try {
const [s, h] = await Promise.all([api.stats(), api.history()]);
setStats(s);
setHistory(h);
} catch {
// stats/history 失败不影响主界面
}
}, []);
useEffect(() => { useEffect(() => {
fetchRates();
fetchAll(); fetchAll();
const interval = setInterval(fetchAll, 2_000); const rateInterval = setInterval(fetchRates, 2_000); // 价格 2秒刷新
return () => clearInterval(interval); const slowInterval = setInterval(fetchAll, 120_000); // 统计 2分钟刷新
}, [fetchAll]); return () => { clearInterval(rateInterval); clearInterval(slowInterval); };
}, [fetchRates, fetchAll]);
return ( return (
<div className="space-y-6"> <div className="space-y-6">