fix(scheduler): drop cross-task mutex, quiet window + retry
Incident: evening full snapshot could be recorded as ok with already_completed/elapsed=0 after mutual skip with hourly sync, then next_run jumped to the next day. - Full-site snapshot never skips because another task is running - 23:00-01:00 Asia/Shanghai: defer discovery / snapshot_recent / candidate_cleanup to after 01:00; fans never defers - Skip records ok=false + skipped=true (not success / not completed) - Skip/fail reschedule soon (~5m); daily success still next snapshot_at - TaskControl return value drives next_run; system UI shows skip fields
This commit is contained in:
1 parent
39378c65b2
commit
9969e65202
10 files changed
+411
-84
No files matched your search
@@ -5,6 +5,15 @@ import {
|
||||
escapeHtml, formatCount, formatDateTime, formatNumber,
|
||||
} from "../format.js";
|
||||
|
||||
function taskResultLabel(record) {
|
||||
const summary = record.summary && typeof record.summary === "object" ? record.summary : {};
|
||||
if (record.skipped || summary.skipped) {
|
||||
return `<span class="muted">跳过</span>`;
|
||||
}
|
||||
if (record.ok) return "成功";
|
||||
return `<span class="danger">失败</span>`;
|
||||
}
|
||||
|
||||
function taskRows(tasks) {
|
||||
const entries = Object.entries(tasks || {});
|
||||
if (!entries.length) return emptyState("暂无任务记录", "运行一次同步、快照或发现后会写入最近结果。");
|
||||
@@ -15,12 +24,16 @@ function taskRows(tasks) {
|
||||
${entries.map(([name, record]) => {
|
||||
const summary = record.summary && typeof record.summary === "object"
|
||||
? Object.entries(record.summary)
|
||||
.filter(([key]) => ["added", "removed", "candidates", "notified", "ok", "failed", "total", "completed", "backup_error"].includes(key))
|
||||
.filter(([key]) => [
|
||||
"added", "removed", "candidates", "notified", "ok", "failed",
|
||||
"total", "completed", "backup_error", "skipped", "already_completed",
|
||||
"reason", "elapsed", "success",
|
||||
].includes(key))
|
||||
.map(([key, value]) => `${key}=${value}`).join(" ")
|
||||
: "";
|
||||
return `<tr>
|
||||
<td>${escapeHtml(name)}</td>
|
||||
<td>${record.ok ? "成功" : `<span class="danger">失败</span>`}</td>
|
||||
<td>${taskResultLabel(record)}</td>
|
||||
<td>${escapeHtml(formatDateTime(record.finished_at))}</td>
|
||||
<td class="summary-cell">${escapeHtml(summary || record.error || "—")}</td>
|
||||
</tr>`;
|
||||
@@ -100,7 +113,7 @@ export async function renderSystem(root) {
|
||||
<div><span>新视频小时同步</span><strong>${running.snapshot_recent ? "运行中" : escapeHtml(formatDateTime(next.snapshot_recent))}</strong></div>
|
||||
<div><span>新视频搜索</span><strong>${running.discover || running.discovery ? "运行中" : escapeHtml(formatDateTime(next.discover))}</strong></div>
|
||||
</div>
|
||||
<p class="section-note">进行中显示「运行中」;空闲时按该任务上次完成时间推算下次运行,不按墙钟抢跑。新视频小时同步与全站快照互斥。</p>
|
||||
<p class="section-note">进行中显示「运行中」;空闲时按该任务上次完成时间推算下次运行。23:00–01:00(上海)为全站快照窗:发现 / 小时同步 / 候选清理会延后到 01:00 后;粉丝更新不避开。跳过或失败不会记成成功,会短间隔补跑。</p>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
|
||||
Reference in new issue
Block a user