task-31: 连续失败计数
useTaskProgressLoop 轮询循环维护连续失败计数:refreshOnce 成功 (收到响应)归零;失败递增(封顶 100);onError 回调增加第二参数 attempt(0 起),供上层决定退避策略;dispose 后不再上报。 同时把该组合式函数内部 @/ 别名 import 改为相对路径(带 .ts 扩展), 使其可在 node --test 下直接运行(此前无任何测试覆盖该文件)。 新增 8 个测试:递增、成功后归零、收到响应归零、onError 带 attempt、 初始 0、交错、封顶、dispose 清理。
This commit is contained in:
@@ -4,20 +4,20 @@ import {
|
||||
getTaskPollBackoffMs,
|
||||
getTaskForegroundRefreshEnabled,
|
||||
getTaskForegroundRefreshDelayMs,
|
||||
} from '@/shared/task-progress-config'
|
||||
import { createCategorizedTimers } from '@/shared/utils/categorized-timers'
|
||||
} from '../task-progress-config.ts'
|
||||
import { createCategorizedTimers } from '../utils/categorized-timers.ts'
|
||||
import {
|
||||
createTaskPollingBaseline,
|
||||
type TaskPollingBaseline,
|
||||
} from '@/shared/task-polling-baseline'
|
||||
} from '../task-polling-baseline.ts'
|
||||
import {
|
||||
createProgressResponseCache,
|
||||
type ProgressResponseCache,
|
||||
} from '@/shared/progress-response-cache'
|
||||
} from '../progress-response-cache.ts'
|
||||
import {
|
||||
createTaskPollingCoordinator,
|
||||
type TaskPollingCoordinator,
|
||||
} from '@/shared/task-polling-coordinator'
|
||||
} from '../task-polling-coordinator.ts'
|
||||
|
||||
/**
|
||||
* 通用任务进度轮询组合式函数。
|
||||
@@ -59,8 +59,11 @@ export interface TaskProgressLoopOptions<TDetail> {
|
||||
* 若多个任务同一轮到达终态,会被分别回调。
|
||||
*/
|
||||
onTerminal?: (taskId: number, detail: TDetail | undefined, status: string) => void | Promise<void>
|
||||
/** 轮询周期失败时的回调;默认静默 */
|
||||
onError?: (error: unknown) => void
|
||||
/**
|
||||
* 轮询周期失败时的回调;默认静默。
|
||||
* 第二个参数 attempt 为连续失败计数(0 起,成功后归零),供上层决定退避策略。
|
||||
*/
|
||||
onError?: (error: unknown, attempt?: number) => void
|
||||
/** 自定义轮询间隔;默认根据 document.visibilityState 自适应(5s/30s) */
|
||||
getIntervalMs?: () => number
|
||||
/**
|
||||
@@ -138,6 +141,7 @@ export function useTaskProgressLoop<TDetail>(
|
||||
const inFlight = ref(false)
|
||||
let pollTimer: number | null = null
|
||||
let disposed = false
|
||||
let failureCount = 0
|
||||
|
||||
function persist() {
|
||||
writeIdsToStorage(options.storageKey, taskIds.value)
|
||||
@@ -204,6 +208,7 @@ export function useTaskProgressLoop<TDetail>(
|
||||
}
|
||||
}
|
||||
taskStatuses.value = nextStatuses
|
||||
failureCount = 0
|
||||
for (const event of terminalEvents) {
|
||||
coordinator?.markTerminal(event.taskId)
|
||||
remove(event.taskId)
|
||||
@@ -214,7 +219,11 @@ export function useTaskProgressLoop<TDetail>(
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
options.onError?.(error)
|
||||
if (!disposed) {
|
||||
const attempt = failureCount
|
||||
failureCount = Math.min(failureCount + 1, 100)
|
||||
options.onError?.(error, attempt)
|
||||
}
|
||||
} finally {
|
||||
inFlight.value = false
|
||||
if (baseline) options.onBaseline?.(baseline)
|
||||
|
||||
Reference in New Issue
Block a user