fix: 修复整合包失败后的完整重试流程
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Sync LobeHub models / sync (push) Has been cancelled

This commit is contained in:
Disy committed 2026-09-19 00:13:43 +08:00
1 parent 392f01ea4b
commit a47d309103
8 files changed
+266 -32

No files matched your search

@@ -13,7 +13,6 @@ import type { Router } from 'vue-router'
import {
install_job_dismiss,
install_job_repair_cache_and_retry,
install_job_retry,
install_job_support_details,
installJobInstanceId,
type InstallJobSnapshot,
@@ -674,7 +673,7 @@ export async function useInstallJobNotifications(opts: {
action: async () => {
if (repairingJobIds.value.has(job.job_id)) return
if (!requiresCacheRepair) {
await install_job_retry(job.job_id).catch(opts.handleError)
await opts.manager.retry(job.job_id).catch(opts.handleError)
await refresh()
return
}
@@ -1,6 +1,8 @@
import { ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { hostedCreate, hostedSync } from '../helpers/hosted-packs.ts'
import { ref } from 'vue'
import { hostedCreate } from '../helpers/hosted-packs.ts'
import { runHostedSync } from './useHostedSync.ts'
const installing = ref(false)
const installError = ref('')
@@ -16,6 +18,18 @@ export function forgetHostedCreation(instanceId: string) {
installError.value = ''
}
export function markHostedCreationCompleted(instanceId: string) {
if (createdInstance.value !== instanceId) return
installError.value = ''
completed.value = true
}
export function markHostedCreationFailed(instanceId: string, cause: unknown) {
if (createdInstance.value !== instanceId) return
completed.value = false
installError.value = String(cause)
}
export function useHostedCreation() {
function acknowledge(instanceId: string) {
if (completed.value && createdInstance.value === instanceId) {
@@ -42,12 +56,15 @@ export function useHostedCreation() {
if (completed.value) return createdInstance.value
createdInstance.value ??= await hostedCreate(gameDirRoot)
const instanceId = createdInstance.value
await hostedSync(instanceId)
await runHostedSync(instanceId)
if (attempt !== generation) return
completed.value = true
markHostedCreationCompleted(instanceId)
return instanceId
} catch (cause) {
if (attempt === generation) installError.value = String(cause)
if (attempt === generation) {
if (createdInstance.value) markHostedCreationFailed(createdInstance.value, cause)
else installError.value = String(cause)
}
} finally {
installing.value = false
}
@@ -1,30 +1,59 @@
import { computed, reactive } from 'vue'
import { hostedSync, type HostedSyncResult } from '../helpers/hosted-packs.ts'
const tasks = reactive(
new Map<string, { busy: boolean; result: HostedSyncResult | null; error: string }>(),
)
const inFlight = new Map<string, Promise<HostedSyncResult>>()
function getTask(instanceId: string) {
if (!tasks.has(instanceId)) tasks.set(instanceId, { busy: false, result: null, error: '' })
return tasks.get(instanceId)!
}
/**
* Run one authoritative StarLight synchronization per instance. Every retry
* surface uses this function so the full pack transaction, its progress and
* its final result cannot diverge between pages.
*/
export function runHostedSync(instanceId: string): Promise<HostedSyncResult> {
const existing = inFlight.get(instanceId)
if (existing) return existing
const current = getTask(instanceId)
current.busy = true
current.error = ''
current.result = null
const request = hostedSync(instanceId)
.then((result) => {
current.result = result
return result
})
.catch((error) => {
current.error = String(error)
throw error
})
.finally(() => {
current.busy = false
inFlight.delete(instanceId)
})
inFlight.set(instanceId, request)
return request
}
export function useHostedSync(instanceId: () => string) {
const task = computed(() => {
const id = instanceId()
if (!tasks.has(id)) tasks.set(id, { busy: false, result: null, error: '' })
return tasks.get(id)!
return getTask(instanceId())
})
async function sync() {
const id = instanceId()
const current = task.value
if (current.busy) return
current.busy = true
current.error = ''
current.result = null
if (task.value.busy) return undefined
try {
current.result = await hostedSync(id)
} catch (error) {
current.error = String(error)
} finally {
current.busy = false
return await runHostedSync(id)
} catch {
return undefined
}
}