fix(web-ui): 搜索索引前端超时 15s→120s + 后端单飞去重

问题:另一台机器首次加载报 'signal is aborted without reason'——
不是取不到数据,是前端 AbortController 15 秒就掐断了请求,但遮罩
却告诉用户等 30-60 秒,自相矛盾。

修复:
- 前端 fetchSearchIndex 超时 15s → 120s:遮罩本就是要等的,不能自己掐断
- 后端 _build_search_index 单飞去重:用 asyncio.Future 让 lifespan 预热
  与 /security/search-index 端点请求共享同一任务,避免并发各爬一次全名单
  (两个任务抢同一把 _execute_lock 反而互相拖慢)
- lifespan 预热改为调 _build_search_index(复用单飞),加 120s 超时保护
This commit is contained in:
Justin Gu
2026-07-06 02:31:20 +08:00
parent 6b01c0687c
commit 04fd720a05
3 changed files with 61 additions and 19 deletions
+3 -3
View File
@@ -105,11 +105,11 @@ export async function fetchBars(
/** 拉取股票搜索索引(code/name/initials,约 5000 条,~150KB)。
* 前端 useStockSearch 会模块级缓存,整个会话只拉一次。
* 超时 15 秒放弃——后端首次构建索引要走全量 get_security_list_all(几十秒),
* 超时后放弃可避免长时间独占共享连接、阻塞 /bars 行情请求。 */
* 超时 120 秒——后端首次构建索引要走全量 get_security_list_all(几十秒),
* AppInitOverlay 遮罩期间用户本就在等待,不能过早 abort。 */
export async function fetchSearchIndex(): Promise<StockSearchIndex> {
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), 15_000)
const timer = setTimeout(() => controller.abort(), 120_000)
try {
const resp = await fetch(`${BASE}/security/search-index`, { signal: controller.signal })
if (!resp.ok) await throwError(resp)