fix profile runtime status loading (#1142)

This commit is contained in:
ekko
2026-05-30 09:17:37 +08:00
committed by GitHub
parent a1f06b8a42
commit 675ddb8282
12 changed files with 136 additions and 14 deletions
+11 -1
View File
@@ -52,6 +52,11 @@ export interface ProfileRuntimeStatus {
}
}
export interface ProfileRuntimeStatusesResponse {
profiles: ProfileRuntimeStatus[]
refreshing?: boolean
}
export async function fetchProfiles(): Promise<HermesProfile[]> {
const res = await request<{ profiles: HermesProfile[] }>('/api/hermes/profiles')
return res.profiles
@@ -66,8 +71,13 @@ export async function fetchProfileRuntimeStatus(name: string): Promise<ProfileRu
return request<ProfileRuntimeStatus>(`/api/hermes/profiles/${encodeURIComponent(name)}/runtime-status`)
}
export async function fetchProfileRuntimeStatusesWithMeta(options: { refresh?: boolean } = {}): Promise<ProfileRuntimeStatusesResponse> {
const query = options.refresh === false ? '?refresh=0' : ''
return request<ProfileRuntimeStatusesResponse>(`/api/hermes/profiles/runtime-statuses${query}`)
}
export async function fetchProfileRuntimeStatuses(): Promise<ProfileRuntimeStatus[]> {
const res = await request<{ profiles: ProfileRuntimeStatus[] }>('/api/hermes/profiles/runtime-statuses')
const res = await fetchProfileRuntimeStatusesWithMeta()
return res.profiles
}
@@ -3,7 +3,7 @@ import { computed, onMounted, ref } from 'vue'
import { NButton, NModal, NSpin, useMessage } from 'naive-ui'
import { useProfilesStore } from '@/stores/hermes/profiles'
import {
fetchProfileRuntimeStatuses,
fetchProfileRuntimeStatusesWithMeta,
restartProfileGateway,
restartProfileRuntime,
type HermesProfile,
@@ -31,21 +31,43 @@ const gatewayRestarting = ref<Record<string, boolean>>({})
const profileRestarting = ref<Record<string, boolean>>({})
const profileSwitching = ref<Record<string, boolean>>({})
const statusByProfile = computed(() => new Map(runtimeStatuses.value.map(status => [status.profile, status])))
let runtimeRefreshToken = 0
async function loadRuntimeStatuses() {
runtimeLoading.value = true
async function loadRuntimeStatuses(options: { background?: boolean } = {}): Promise<boolean> {
const token = ++runtimeRefreshToken
if (!options.background) {
runtimeLoading.value = runtimeStatuses.value.length === 0
}
try {
runtimeStatuses.value = await fetchProfileRuntimeStatuses()
const res = await fetchProfileRuntimeStatusesWithMeta({ refresh: !options.background })
if (token !== runtimeRefreshToken) return false
runtimeStatuses.value = res.profiles
return !!res.refreshing
} catch {
runtimeStatuses.value = []
return false
} finally {
runtimeLoading.value = false
if (token === runtimeRefreshToken) {
runtimeLoading.value = false
}
}
}
function openProfileModal() {
showProfileModal.value = true
void loadRuntimeStatuses()
void loadRuntimeStatuses().then((refreshing) => {
if (refreshing) scheduleRuntimeStatusPoll()
})
}
function scheduleRuntimeStatusPoll(attempt = 0) {
if (attempt >= 12 || typeof window === 'undefined') return
window.setTimeout(() => {
if (!showProfileModal.value) return
void loadRuntimeStatuses({ background: true }).then((refreshing) => {
if (refreshing) scheduleRuntimeStatusPoll(attempt + 1)
})
}, attempt === 0 ? 700 : 1200)
}
function openAvatarModal(profile: HermesProfile) {
@@ -116,10 +138,12 @@ async function handleAvatarFileChange(event: Event) {
}
function gatewayStatusText(running?: boolean) {
if (running == null) return t('profiles.runtime.checking')
return running ? t('profiles.runtime.running') : t('profiles.runtime.stopped')
}
function bridgeStatusText(running?: boolean) {
if (running == null) return t('profiles.runtime.checking')
return running ? t('profiles.runtime.active') : t('profiles.runtime.idle')
}
+1
View File
@@ -706,6 +706,7 @@ jobTriggered: 'Job ausgelost',
active: 'Aktiv',
activeTag: 'Aktuell',
idle: 'Leerlauf',
checking: 'Prüfung läuft',
running: 'Läuft',
stopped: 'Gestoppt',
restartGateway: 'Gateway neu starten',
+1
View File
@@ -809,6 +809,7 @@ export default {
active: 'Active',
activeTag: 'Active',
idle: 'Idle',
checking: 'Checking',
running: 'Running',
stopped: 'Stopped',
restartGateway: 'Restart Gateway',
+1
View File
@@ -706,6 +706,7 @@ jobTriggered: 'Job ejecutado',
active: 'Activo',
activeTag: 'Actual',
idle: 'Inactivo',
checking: 'Comprobando',
running: 'En ejecución',
stopped: 'Detenido',
restartGateway: 'Reiniciar gateway',
+1
View File
@@ -706,6 +706,7 @@ jobTriggered: 'Job declenche',
active: 'Actif',
activeTag: 'Actuel',
idle: 'Inactif',
checking: 'Vérification',
running: 'En cours',
stopped: 'Arrêté',
restartGateway: 'Redémarrer le gateway',
+1
View File
@@ -706,6 +706,7 @@ export default {
active: 'アクティブ',
activeTag: '現在',
idle: '待機中',
checking: '確認中',
running: '実行中',
stopped: '停止中',
restartGateway: 'Gateway を再起動',
+1
View File
@@ -706,6 +706,7 @@ export default {
active: '활성',
activeTag: '현재',
idle: '대기 중',
checking: '확인 중',
running: '실행 중',
stopped: '중지됨',
restartGateway: 'Gateway 재시작',
+1
View File
@@ -706,6 +706,7 @@ jobTriggered: 'Job acionado',
active: 'Ativo',
activeTag: 'Atual',
idle: 'Ocioso',
checking: 'Verificando',
running: 'Em execução',
stopped: 'Parado',
restartGateway: 'Reiniciar gateway',
@@ -801,6 +801,7 @@ export default {
active: '使用中',
activeTag: '目前',
idle: '閒置',
checking: '檢測中',
running: '執行中',
stopped: '已停止',
restartGateway: '重啟閘道',
+1
View File
@@ -801,6 +801,7 @@ export default {
active: '活跃',
activeTag: '当前',
idle: '空闲',
checking: '检测中',
running: '运行中',
stopped: '已停止',
restartGateway: '重启网关',