mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-11 18:10:41 +08:00
perf: ARM设备性能优化 — in-flight请求去重+后端缓存+仪表盘轮询降频+R2 CDN加速
This commit is contained in:
@@ -220,7 +220,7 @@ let _pollTimer = null
|
||||
/** 启动 Gateway 状态轮询(每 15 秒,避免过于频繁) */
|
||||
export function startGatewayPoll() {
|
||||
if (_pollTimer) return
|
||||
_pollTimer = setInterval(() => refreshGatewayStatus(), 15000)
|
||||
_pollTimer = setInterval(() => refreshGatewayStatus(), 30000)
|
||||
}
|
||||
export function stopGatewayPoll() {
|
||||
if (_pollTimer) { clearInterval(_pollTimer); _pollTimer = null }
|
||||
|
||||
@@ -19,6 +19,7 @@ const _invokeReady = isTauri
|
||||
|
||||
// 简单缓存:避免页面切换时重复请求后端
|
||||
const _cache = new Map()
|
||||
const _inflight = new Map() // in-flight 请求去重,防止缓存过期后同一命令并发 spawn 多个进程
|
||||
const CACHE_TTL = 15000 // 15秒
|
||||
|
||||
// 网络请求日志(用于调试)
|
||||
@@ -56,10 +57,21 @@ function cachedInvoke(cmd, args = {}, ttl = CACHE_TTL) {
|
||||
logRequest(cmd, args, 0, true)
|
||||
return Promise.resolve(cached.val)
|
||||
}
|
||||
return invoke(cmd, args).then(val => {
|
||||
// in-flight 去重:同一个 key 的请求正在执行中,复用同一个 Promise
|
||||
// 避免缓存过期瞬间多个调用者同时 spawn 进程(ARM 设备上的 CPU 爆满根因)
|
||||
if (_inflight.has(key)) {
|
||||
return _inflight.get(key)
|
||||
}
|
||||
const p = invoke(cmd, args).then(val => {
|
||||
_cache.set(key, { val, ts: Date.now() })
|
||||
_inflight.delete(key)
|
||||
return val
|
||||
}).catch(err => {
|
||||
_inflight.delete(key)
|
||||
throw err
|
||||
})
|
||||
_inflight.set(key, p)
|
||||
return p
|
||||
}
|
||||
|
||||
// 清除指定命令的缓存(写操作后调用)
|
||||
@@ -147,7 +159,7 @@ export async function checkBackendHealth() {
|
||||
// 导出 API
|
||||
export const api = {
|
||||
// 服务管理(状态用短缓存,操作不缓存)
|
||||
getServicesStatus: () => cachedInvoke('get_services_status', {}, 3000),
|
||||
getServicesStatus: () => cachedInvoke('get_services_status', {}, 10000),
|
||||
startService: (label) => { invalidate('get_services_status'); return invoke('start_service', { label }) },
|
||||
stopService: (label) => { invalidate('get_services_status'); return invoke('stop_service', { label }) },
|
||||
restartService: (label) => { invalidate('get_services_status'); return invoke('restart_service', { label }) },
|
||||
@@ -155,7 +167,7 @@ export const api = {
|
||||
|
||||
// 配置(读缓存,写清缓存)
|
||||
getVersionInfo: () => cachedInvoke('get_version_info', {}, 30000),
|
||||
getStatusSummary: () => cachedInvoke('get_status_summary', {}, 5000),
|
||||
getStatusSummary: () => cachedInvoke('get_status_summary', {}, 60000),
|
||||
readOpenclawConfig: () => cachedInvoke('read_openclaw_config'),
|
||||
writeOpenclawConfig: (config) => { invalidate('read_openclaw_config'); return invoke('write_openclaw_config', { config }) },
|
||||
readMcpConfig: () => cachedInvoke('read_mcp_config'),
|
||||
|
||||
@@ -56,18 +56,23 @@ export function cleanup() {
|
||||
if (_unsubGw) { _unsubGw(); _unsubGw = null }
|
||||
}
|
||||
|
||||
async function loadDashboardData(page) {
|
||||
let _dashboardInitialized = false
|
||||
|
||||
async function loadDashboardData(page, fullRefresh = false) {
|
||||
// 分波加载:关键数据先渲染,次要数据后填充,减少白屏等待
|
||||
// 轻量调用(读文件)每次都做;重量调用(spawn CLI/网络请求)只在首次或手动刷新时做
|
||||
const coreP = Promise.allSettled([
|
||||
api.getServicesStatus(),
|
||||
api.getVersionInfo(),
|
||||
api.readOpenclawConfig(),
|
||||
// 版本信息:首次加载或手动刷新时才查询(避免 ARM 设备上频繁查 npm registry)
|
||||
(!_dashboardInitialized || fullRefresh) ? api.getVersionInfo() : Promise.resolve(null),
|
||||
])
|
||||
const secondaryP = Promise.allSettled([
|
||||
api.listAgents(),
|
||||
api.readMcpConfig(),
|
||||
api.listBackups(),
|
||||
api.getStatusSummary(),
|
||||
// getStatusSummary 是最重的调用(spawn openclaw status --json),只在首次加载时调用
|
||||
(!_dashboardInitialized || fullRefresh) ? api.getStatusSummary() : Promise.resolve(null),
|
||||
])
|
||||
const logsP = api.readLogTail('gateway', 20).catch(() => '')
|
||||
|
||||
@@ -111,6 +116,8 @@ async function loadDashboardData(page) {
|
||||
// 第三波:日志(最低优先级)
|
||||
const logs = await logsP
|
||||
renderLogs(page, logs)
|
||||
|
||||
_dashboardInitialized = true
|
||||
}
|
||||
|
||||
function renderStatCards(page, services, version, agents, config) {
|
||||
|
||||
Reference in New Issue
Block a user