perf(api): HostAggregator 效能優化 — probe timeout 縮短 + 30 秒記憶體快取
This commit is contained in:
@@ -197,7 +197,7 @@ def get_baseline_context_for_llm(metrics: HostMetrics, host_name: str) -> str:
|
||||
# Real Host Probing
|
||||
# =============================================================================
|
||||
|
||||
async def _tcp_probe(ip: str, port: int, timeout: float = 3.0) -> tuple[bool, float | None, str | None]:
|
||||
async def _tcp_probe(ip: str, port: int, timeout: float = 1.5) -> tuple[bool, float | None, str | None]:
|
||||
"""
|
||||
Real TCP port probe using asyncio.open_connection
|
||||
|
||||
@@ -236,7 +236,7 @@ async def _http_probe(
|
||||
ip: str,
|
||||
port: int,
|
||||
path: str,
|
||||
timeout: float = 5.0,
|
||||
timeout: float = 2.0,
|
||||
https: bool = False
|
||||
) -> tuple[bool, float | None, str | None]:
|
||||
"""
|
||||
@@ -328,8 +328,18 @@ class HostAggregator:
|
||||
|
||||
Uses asyncio.gather for parallel fetching of all host statuses.
|
||||
Performs real TCP/HTTP probes to determine service availability.
|
||||
|
||||
2026-04-08 Claude Code: Sprint 5 效能優化
|
||||
- TCP timeout: 3.0s → 1.5s
|
||||
- HTTP timeout: 5.0s → 2.0s
|
||||
- 記憶體快取: 上次成功結果 + 30 秒 TTL
|
||||
"""
|
||||
|
||||
# 記憶體快取 (避免 probe 超時時前端空白)
|
||||
_cache: AggregatedStatus | None = None
|
||||
_cache_time: float = 0
|
||||
_CACHE_TTL = 30 # 秒
|
||||
|
||||
@classmethod
|
||||
async def _probe_service(
|
||||
cls,
|
||||
@@ -425,6 +435,7 @@ class HostAggregator:
|
||||
metrics=metrics,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@classmethod
|
||||
async def fetch_all(cls) -> AggregatedStatus:
|
||||
"""
|
||||
@@ -432,7 +443,15 @@ class HostAggregator:
|
||||
|
||||
Uses asyncio.gather for maximum concurrency.
|
||||
Always performs real probing - no mock data.
|
||||
快取: 30 秒內返回快取結果,避免前端等待超時
|
||||
"""
|
||||
import time as _time
|
||||
|
||||
# 快取命中: 30 秒內直接回傳
|
||||
now = _time.monotonic()
|
||||
if cls._cache is not None and (now - cls._cache_time) < cls._CACHE_TTL:
|
||||
return cls._cache
|
||||
|
||||
logger.info("aggregator_fetch_start", mode="real_probing")
|
||||
|
||||
# Fetch all hosts in parallel
|
||||
@@ -480,7 +499,7 @@ class HostAggregator:
|
||||
host_statuses={h.ip: h.status for h in hosts},
|
||||
)
|
||||
|
||||
return AggregatedStatus(
|
||||
result = AggregatedStatus(
|
||||
timestamp=datetime.now(UTC),
|
||||
environment=settings.ENVIRONMENT,
|
||||
mock_mode=False, # Always real mode
|
||||
@@ -488,6 +507,12 @@ class HostAggregator:
|
||||
hosts=hosts,
|
||||
)
|
||||
|
||||
# 更新快取
|
||||
cls._cache = result
|
||||
cls._cache_time = _time.monotonic()
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
async def fetch_single(cls, ip: str) -> HostStatus | None:
|
||||
"""Fetch status from a single host"""
|
||||
|
||||
Reference in New Issue
Block a user