优化后台业务
This commit is contained in:
@@ -333,6 +333,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 MAX_TRANSIENT_ERRORS = 30;
|
||||
|
||||
@@ -358,6 +359,7 @@ const activeQueueItem = ref<QueryAsinShopQueueItem | null>(null);
|
||||
const queueWorkerRunning = ref(false);
|
||||
const autoQueueEnabled = ref(false);
|
||||
let historyPollTimer: number | null = null;
|
||||
const timers = createCategorizedTimers("query-asin");
|
||||
|
||||
const matchedRunnableItems = computed(() =>
|
||||
matchedItems.value.filter((item) => item.matched && (item.queryAsins || []).some((row) => row.asins?.length)),
|
||||
@@ -398,8 +400,15 @@ function historyItemKey(item: QueryAsinHistoryItem) {
|
||||
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) {
|
||||
@@ -424,6 +433,7 @@ async function withTransientRetry<T>(
|
||||
) {
|
||||
let attempt = 0;
|
||||
while (true) {
|
||||
if (disposed) throw new Error("component disposed");
|
||||
try {
|
||||
return await action();
|
||||
} catch (error) {
|
||||
@@ -747,21 +757,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;
|
||||
}
|
||||
}
|
||||
@@ -893,6 +903,7 @@ function findHistoryItemByTaskId(taskId: number) {
|
||||
async function waitForTaskTerminal(taskId: number) {
|
||||
let transientErrorCount = 0;
|
||||
while (true) {
|
||||
if (disposed) return "STOPPED";
|
||||
try {
|
||||
await refreshActiveTaskProgress([taskId]);
|
||||
if (activeTaskId.value !== taskId) {
|
||||
@@ -924,7 +935,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();
|
||||
@@ -935,7 +946,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 =
|
||||
@@ -1002,6 +1013,7 @@ async function processQueue() {
|
||||
await refreshTaskViews();
|
||||
ElMessage.success("查询ASIN队列已按顺序执行完成");
|
||||
} catch (error) {
|
||||
if (disposed) return;
|
||||
const message = error instanceof Error ? error.message : "队列执行失败";
|
||||
queuePushResult.value = message;
|
||||
ElMessage.error(message);
|
||||
@@ -1092,7 +1104,10 @@ onMounted(async () => {
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
disposed = true;
|
||||
stopHistoryPolling();
|
||||
clearSleepTimers();
|
||||
timers.clearScope();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user