Add market watch and match hub workflows

这个提交包含在:
cryptocommuniums-afk
2026-04-07 11:00:03 +08:00
父节点 495da60212
当前提交 32ffad1545
修改 39 个文件,包含 6974 行新增330 行删除

查看文件

@@ -9,6 +9,20 @@ function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function isRetriableBackgroundError(error: unknown) {
if (!(error instanceof Error)) return false;
return (
error.message.startsWith("Request timed out after ") ||
error.message.includes("fetch failed") ||
error.message.includes("ECONNRESET") ||
error.message.includes("ETIMEDOUT") ||
error.message.includes("429") ||
error.message.includes("502") ||
error.message.includes("503") ||
error.message.includes("504")
);
}
async function workOnce() {
await db.failExhaustedBackgroundTasks();
await db.requeueStaleBackgroundTasks(new Date(Date.now() - ENV.backgroundTaskStaleMs));
@@ -31,9 +45,21 @@ async function workOnce() {
}
} catch (error) {
const message = error instanceof Error ? error.message : "Unknown background task error";
await db.failBackgroundTask(task.id, message);
await db.failVisionTestRun(task.id, message);
console.error(`[worker] task ${task.id} failed:`, error);
if (isRetriableBackgroundError(error) && task.attempts < task.maxAttempts) {
const nextAttempt = task.attempts + 1;
const delayMs = Math.min(30_000, 5_000 * task.attempts);
await db.rescheduleBackgroundTask(task.id, {
progress: 15,
message: `请求超时,已自动重试(第 ${nextAttempt}/${task.maxAttempts} 次尝试)`,
error: message,
delayMs,
});
console.warn(`[worker] task ${task.id} rescheduled after retriable error:`, error);
} else {
await db.failBackgroundTask(task.id, message);
await db.failVisionTestRun(task.id, message);
console.error(`[worker] task ${task.id} failed:`, error);
}
} finally {
clearInterval(heartbeatTimer);
}