62 lines
1.5 KiB
JavaScript
62 lines
1.5 KiB
JavaScript
import { ref } from 'vue'
|
|
|
|
import { fetchBackendHealth } from '../services/system.js'
|
|
|
|
const backendHealthy = ref(true)
|
|
const backendChecking = ref(false)
|
|
const backendError = ref('')
|
|
let lastCheckedAt = 0
|
|
const DEFAULT_HEALTH_TIMEOUT_MS = 2500
|
|
const REQUEST_TIMEOUT_CODE = 'REQUEST_TIMEOUT'
|
|
|
|
function isRequestTimeout(error) {
|
|
return error?.code === REQUEST_TIMEOUT_CODE
|
|
}
|
|
|
|
export async function checkBackendHealth(options = {}) {
|
|
const force = Boolean(options.force)
|
|
const now = Date.now()
|
|
|
|
if (!force && now - lastCheckedAt < 5000) {
|
|
return backendHealthy.value
|
|
}
|
|
|
|
backendChecking.value = true
|
|
|
|
try {
|
|
const payload = await fetchBackendHealth({
|
|
timeoutMs: Number(options.timeoutMs || DEFAULT_HEALTH_TIMEOUT_MS)
|
|
})
|
|
const ok = payload?.status === 'ok'
|
|
|
|
backendHealthy.value = ok
|
|
backendError.value = ok
|
|
? ''
|
|
: payload?.database?.error || '后端服务尚未准备完成。'
|
|
lastCheckedAt = now
|
|
return ok
|
|
} catch (error) {
|
|
if (isRequestTimeout(error) && options.allowStaleOnTimeout) {
|
|
backendError.value = error?.message || '后端正在处理耗时任务,已先展示页面。'
|
|
lastCheckedAt = now
|
|
return backendHealthy.value !== false
|
|
}
|
|
|
|
backendHealthy.value = false
|
|
backendError.value = error?.message || '无法连接后端服务。'
|
|
lastCheckedAt = now
|
|
return false
|
|
} finally {
|
|
backendChecking.value = false
|
|
}
|
|
}
|
|
|
|
export function useBackendHealth() {
|
|
return {
|
|
backendHealthy,
|
|
backendChecking,
|
|
backendError,
|
|
checkBackendHealth
|
|
}
|
|
}
|