优化后台业务
This commit is contained in:
@@ -334,6 +334,7 @@ import {
|
||||
} from "@/shared/api/java-modules";
|
||||
import { getPywebviewApi } from "@/shared/bridges/pywebview";
|
||||
import { getTaskPollIntervalMs } from "@/shared/task-progress-config";
|
||||
import { createCategorizedTimers } from "@/shared/utils/categorized-timers";
|
||||
|
||||
const COUNTRY_TEMPLATE = ["德国", "英国", "法国", "意大利", "西班牙"] as const;
|
||||
const MAX_TRANSIENT_ERRORS = 30;
|
||||
@@ -360,6 +361,7 @@ const activeQueueItem = ref<PatrolDeleteShopQueueItem | null>(null);
|
||||
const queueWorkerRunning = ref(false);
|
||||
const autoQueueEnabled = ref(false);
|
||||
let historyPollTimer: number | null = null;
|
||||
const timers = createCategorizedTimers("patrol-delete");
|
||||
|
||||
const matchedRunnableItems = computed(() =>
|
||||
matchedItems.value.filter((item) => item.matched),
|
||||
@@ -399,8 +401,15 @@ function historyItemKey(item: PatrolDeleteHistoryItem) {
|
||||
return `${item.taskId ?? 0}:${item.resultId ?? 0}`;
|
||||
}
|
||||
|
||||
let disposed = false;
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => window.setTimeout(resolve, ms));
|
||||
if (disposed) return Promise.resolve();
|
||||
return timers.sleep("queue-wait", ms);
|
||||
}
|
||||
|
||||
function clearSleepTimers() {
|
||||
timers.clearCategory("queue-wait");
|
||||
}
|
||||
|
||||
function isTransientBackendError(error: unknown) {
|
||||
@@ -425,6 +434,7 @@ async function withTransientRetry<T>(
|
||||
) {
|
||||
let attempt = 0;
|
||||
while (true) {
|
||||
if (disposed) throw new Error("component disposed");
|
||||
try {
|
||||
return await action();
|
||||
} catch (error) {
|
||||
@@ -716,21 +726,21 @@ async function refreshActiveTaskProgress(taskIds?: number[]) {
|
||||
|
||||
function startHistoryPolling() {
|
||||
stopHistoryPolling();
|
||||
if (!hasQueueWork.value) return;
|
||||
if (disposed || !hasQueueWork.value) return;
|
||||
const run = async () => {
|
||||
historyPollTimer = null;
|
||||
if (!hasQueueWork.value) return;
|
||||
if (disposed || !hasQueueWork.value) return;
|
||||
await refreshActiveTaskProgress();
|
||||
if (hasQueueWork.value) {
|
||||
historyPollTimer = window.setTimeout(run, getTaskPollIntervalMs() * 2);
|
||||
if (!disposed && hasQueueWork.value) {
|
||||
historyPollTimer = timers.setTimeout("history-poll", run, getTaskPollIntervalMs() * 2);
|
||||
}
|
||||
};
|
||||
historyPollTimer = window.setTimeout(run, getTaskPollIntervalMs() * 2);
|
||||
historyPollTimer = timers.setTimeout("history-poll", run, getTaskPollIntervalMs() * 2);
|
||||
}
|
||||
|
||||
function stopHistoryPolling() {
|
||||
if (historyPollTimer) {
|
||||
window.clearTimeout(historyPollTimer);
|
||||
timers.clearTimer("history-poll", historyPollTimer);
|
||||
historyPollTimer = null;
|
||||
}
|
||||
}
|
||||
@@ -865,6 +875,7 @@ function findHistoryItemByTaskId(taskId: number) {
|
||||
async function waitForTaskTerminal(taskId: number) {
|
||||
let transientErrorCount = 0;
|
||||
while (true) {
|
||||
if (disposed) return "STOPPED";
|
||||
try {
|
||||
await refreshActiveTaskProgress([taskId]);
|
||||
if (transientErrorCount > 0) {
|
||||
@@ -893,7 +904,7 @@ async function waitForTaskTerminal(taskId: number) {
|
||||
}
|
||||
|
||||
async function processQueue() {
|
||||
if (queueWorkerRunning.value) return;
|
||||
if (disposed || queueWorkerRunning.value) return;
|
||||
queueWorkerRunning.value = true;
|
||||
pushing.value = true;
|
||||
startHistoryPolling();
|
||||
@@ -904,7 +915,7 @@ async function processQueue() {
|
||||
throw new Error("当前客户端未提供 enqueue_json");
|
||||
}
|
||||
|
||||
while (activeTaskId.value || pendingQueue.value.length) {
|
||||
while (!disposed && (activeTaskId.value || pendingQueue.value.length)) {
|
||||
if (activeTaskId.value) {
|
||||
const finalStatus = await waitForTaskTerminal(activeTaskId.value);
|
||||
queuePushResult.value =
|
||||
@@ -975,6 +986,7 @@ async function processQueue() {
|
||||
await refreshTaskViews();
|
||||
ElMessage.success("巡店删除队列已按顺序执行完成");
|
||||
} catch (error) {
|
||||
if (disposed) return;
|
||||
const message = error instanceof Error ? error.message : "队列执行失败";
|
||||
queuePushResult.value = message;
|
||||
ElMessage.error(message);
|
||||
@@ -1061,7 +1073,10 @@ onMounted(async () => {
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
disposed = true;
|
||||
stopHistoryPolling();
|
||||
clearSleepTimers();
|
||||
timers.clearScope();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user