mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-10 17:42:49 +08:00
feat(guardian): 强化Gateway守护与Windows启停安全
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
* 管理 openclaw 安装状态,供各组件查询
|
||||
*/
|
||||
import { api } from './tauri-api.js'
|
||||
import {
|
||||
evaluateAutoRestartAttempt,
|
||||
shouldResetAutoRestartCount,
|
||||
} from './gateway-guardian-policy.js'
|
||||
|
||||
const isTauri = !!window.__TAURI_INTERNALS__
|
||||
|
||||
let _openclawReady = false
|
||||
let _gatewayRunning = false
|
||||
@@ -17,8 +23,7 @@ let _isUpgrading = false // 升级/切换版本期间,阻止 setup 跳转
|
||||
let _userStopped = false // 用户主动停止,不自动拉起
|
||||
let _autoRestartCount = 0 // 自动重启次数
|
||||
let _lastRestartTime = 0 // 上次重启时间
|
||||
const MAX_AUTO_RESTART = 3 // 最大连续自动重启次数
|
||||
const RESTART_COOLDOWN = 60000 // 重启冷却期 60s
|
||||
let _gatewayRunningSince = 0 // Gateway 最近一次进入稳定运行状态的时间
|
||||
let _guardianListeners = [] // 守护放弃时的回调
|
||||
|
||||
/** openclaw 是否就绪(CLI 已安装 + 配置文件存在) */
|
||||
@@ -36,7 +41,12 @@ export function isUpgrading() { return _isUpgrading }
|
||||
export function setUserStopped(v) { _userStopped = !!v }
|
||||
|
||||
/** 重置自动重启计数(用户手动启动后重置) */
|
||||
export function resetAutoRestart() { _autoRestartCount = 0; _userStopped = false }
|
||||
export function resetAutoRestart() {
|
||||
_autoRestartCount = 0
|
||||
_lastRestartTime = 0
|
||||
_gatewayRunningSince = 0
|
||||
_userStopped = false
|
||||
}
|
||||
|
||||
/** 监听守护放弃事件(连续重启失败后触发,UI 可弹出恢复选项) */
|
||||
export function onGuardianGiveUp(fn) {
|
||||
@@ -134,11 +144,14 @@ function _setGatewayRunning(val) {
|
||||
_gatewayRunning = val
|
||||
if (changed) {
|
||||
if (val) {
|
||||
// Gateway 恢复运行,重置计数
|
||||
_autoRestartCount = 0
|
||||
} else if (wasRunning && !_userStopped && !_isUpgrading && _openclawReady) {
|
||||
// 仅记录恢复运行时间,避免短暂存活就把重启计数清零
|
||||
_gatewayRunningSince = Date.now()
|
||||
} else if (!isTauri && wasRunning && !_userStopped && !_isUpgrading && _openclawReady) {
|
||||
_gatewayRunningSince = 0
|
||||
// Gateway 意外停止,尝试自动重启
|
||||
_tryAutoRestart()
|
||||
} else if (!val) {
|
||||
_gatewayRunningSince = 0
|
||||
}
|
||||
_gwListeners.forEach(fn => { try { fn(val) } catch {} })
|
||||
}
|
||||
@@ -146,16 +159,23 @@ function _setGatewayRunning(val) {
|
||||
|
||||
async function _tryAutoRestart() {
|
||||
const now = Date.now()
|
||||
// 冷却期内不重复重启
|
||||
if (now - _lastRestartTime < RESTART_COOLDOWN) return
|
||||
if (_autoRestartCount >= MAX_AUTO_RESTART) {
|
||||
console.warn(`[guardian] Gateway 已连续自动重启 ${MAX_AUTO_RESTART} 次,停止守护,请手动检查`)
|
||||
const decision = evaluateAutoRestartAttempt({
|
||||
now,
|
||||
lastRestartTime: _lastRestartTime,
|
||||
autoRestartCount: _autoRestartCount,
|
||||
})
|
||||
|
||||
if (decision.action === 'cooldown') return
|
||||
|
||||
if (decision.action === 'give_up') {
|
||||
console.warn('[guardian] Gateway 已达到自动重启上限,停止守护,请手动检查')
|
||||
_guardianListeners.forEach(fn => { try { fn() } catch {} })
|
||||
return
|
||||
}
|
||||
_autoRestartCount++
|
||||
_lastRestartTime = now
|
||||
console.log(`[guardian] Gateway 意外停止,自动重启 (${_autoRestartCount}/${MAX_AUTO_RESTART})...`)
|
||||
|
||||
_autoRestartCount = decision.autoRestartCount
|
||||
_lastRestartTime = decision.lastRestartTime
|
||||
console.log(`[guardian] Gateway 意外停止,自动重启 (${_autoRestartCount}/3)...`)
|
||||
try {
|
||||
await api.startService('ai.openclaw.gateway')
|
||||
console.log('[guardian] Gateway 自动重启成功')
|
||||
@@ -173,7 +193,15 @@ export async function refreshGatewayStatus() {
|
||||
const nowRunning = services[0]?.running === true
|
||||
if (nowRunning) {
|
||||
_gwStopCount = 0
|
||||
_setGatewayRunning(true)
|
||||
if (!_gatewayRunning) {
|
||||
_setGatewayRunning(true)
|
||||
} else if (shouldResetAutoRestartCount({
|
||||
autoRestartCount: _autoRestartCount,
|
||||
runningSince: _gatewayRunningSince,
|
||||
now: Date.now(),
|
||||
})) {
|
||||
_autoRestartCount = 0
|
||||
}
|
||||
} else {
|
||||
_gwStopCount++
|
||||
if (_gwStopCount >= 2 || !_gatewayRunning) {
|
||||
|
||||
38
src/lib/gateway-guardian-policy.js
Normal file
38
src/lib/gateway-guardian-policy.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Gateway 守护策略
|
||||
* 纯函数,便于测试自动重启与计数重置规则
|
||||
*/
|
||||
|
||||
export const MAX_AUTO_RESTART = 3
|
||||
export const RESTART_COOLDOWN = 60000
|
||||
export const STABLE_RUNNING_MS = 120000
|
||||
|
||||
export function evaluateAutoRestartAttempt({
|
||||
now,
|
||||
lastRestartTime,
|
||||
autoRestartCount,
|
||||
}) {
|
||||
if (now - lastRestartTime < RESTART_COOLDOWN) {
|
||||
return { action: 'cooldown' }
|
||||
}
|
||||
|
||||
if (autoRestartCount >= MAX_AUTO_RESTART) {
|
||||
return { action: 'give_up' }
|
||||
}
|
||||
|
||||
return {
|
||||
action: 'restart',
|
||||
autoRestartCount: autoRestartCount + 1,
|
||||
lastRestartTime: now,
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldResetAutoRestartCount({
|
||||
autoRestartCount,
|
||||
runningSince,
|
||||
now,
|
||||
}) {
|
||||
if (autoRestartCount <= 0) return false
|
||||
if (!runningSince) return false
|
||||
return now - runningSince >= STABLE_RUNNING_MS
|
||||
}
|
||||
Reference in New Issue
Block a user