From 8ff1817845ee51e6fb0c51f90b1bbd04ee26a502 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 8 Oct 2026 03:39:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(sources):=20=E5=BF=AB=E7=85=A7=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E5=89=8D=E6=94=B6=E5=B0=BE=E6=9C=AC=E7=AB=99=E9=81=97?= =?UTF-8?q?=E7=95=99=E7=9A=84=E8=BF=90=E8=A1=8C=E4=B8=AD=E8=AE=B0=E5=BD=95?= =?UTF-8?q?;v0.3.39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei --- CHANGELOG.md | 5 ++++ apps/server/deno.json | 2 +- .../sources-identity/service/snapshot.ts | 12 ++++++++++ .../snapshot-deadline.test.ts | 23 +++++++++++++++++++ apps/web/package.json | 2 +- deno.json | 2 +- packages/adapters/deno.json | 2 +- packages/agent/deno.json | 2 +- packages/contracts/deno.json | 2 +- packages/db/deno.json | 2 +- packages/domain/deno.json | 2 +- packages/mapping/deno.json | 2 +- packages/tasks/deno.json | 2 +- packages/testkit/deno.json | 2 +- 14 files changed, 51 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03605295..c72daff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ 版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。所有成员包(`apps/*`、`packages/*`)与根 `deno.json` 使用同一个版本号;`/api/v1/health` 与备份清单里的版本取自 `apps/server/deno.json`。 +## [0.3.39] - 2026-10-08 + +### 修复 +- 站点快照开始前,把这个站点 10 分钟前就开始、还停在「运行中」的旧快照记录按中断收尾(进程被杀或旧版本卡死留下的;清理任务不删运行中的记录,之前会一直挂在快照历史里)。 + ## [0.3.38] - 2026-10-08 ### 调整 diff --git a/apps/server/deno.json b/apps/server/deno.json index 746137e9..316e1a4d 100644 --- a/apps/server/deno.json +++ b/apps/server/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/server", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/main.ts" }, "tasks": { "dev": "deno run -A --watch --env-file=../../.env src/main.ts", diff --git a/apps/server/src/modules/sources-identity/service/snapshot.ts b/apps/server/src/modules/sources-identity/service/snapshot.ts index 0a780951..b43ae3a2 100644 --- a/apps/server/src/modules/sources-identity/service/snapshot.ts +++ b/apps/server/src/modules/sources-identity/service/snapshot.ts @@ -216,6 +216,18 @@ export async function snapshotSite( if (input.kind === "periodic" || input.kind === "manual") { maxPages = Math.min(maxPages, (await rt.siteAccess(site.key)).snapshotMaxPages); } + // 进程被杀或旧版本卡死留下的「运行中」记录:超过两倍截止时间就按中断收尾(清理任务不删运行中的行) + await db + .updateTable("site_snapshot") + .set({ + status: "failed", + error: jsonb({ kind: "internal", message: "上次快照中断,没有收尾" }), + finished_at: rt.now(), + }) + .where("site_id", "=", site.id) + .where("status", "=", "running") + .where("started_at", "<", new Date(rt.now().getTime() - 2 * (opts.deadlineMs ?? SNAPSHOT_DEADLINE_MS))) + .execute(); const snap = await db .insertInto("site_snapshot") .values({ diff --git a/apps/server/test/sources-identity/snapshot-deadline.test.ts b/apps/server/test/sources-identity/snapshot-deadline.test.ts index 328eec77..21fb75cd 100644 --- a/apps/server/test/sources-identity/snapshot-deadline.test.ts +++ b/apps/server/test/sources-identity/snapshot-deadline.test.ts @@ -59,4 +59,27 @@ describe.skipIf(!up)("快照截止时间", () => { expect(snap.status).toBe("failed"); expect(snap.finished_at).not.toBeNull(); }); + + it("旧的「运行中」记录在下一次快照开始时按中断收尾,刚开始的不动", async () => { + const mk = (ago: number) => + h.db + .insertInto("site_snapshot") + .values({ + site_id: siteId, + kind: "periodic", + filters: "{}", + definition_version: "t", + started_at: new Date(Date.now() - ago), + }) + .returning("id") + .executeTakeFirstOrThrow(); + const stale = await mk(3_600_000); + const fresh = await mk(100); + await snapshotSite(h.rt, { siteId, kind: "periodic" }, { deadlineMs: 300 }); + const get = (id: string) => + h.db.selectFrom("site_snapshot").selectAll().where("id", "=", id).executeTakeFirstOrThrow(); + expect(await get(stale.id)).toMatchObject({ status: "failed" }); + expect((await get(stale.id)).error).toMatchObject({ message: "上次快照中断,没有收尾" }); + expect((await get(fresh.id)).status).toBe("running"); + }); }); diff --git a/apps/web/package.json b/apps/web/package.json index 28a63dd9..1bf6754c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@umt/web", - "version": "0.3.38", + "version": "0.3.39", "private": true, "type": "module", "scripts": { diff --git a/deno.json b/deno.json index 6cf66dae..9379f21b 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,5 @@ { - "version": "0.3.38", + "version": "0.3.39", "workspace": [ "./packages/adapters", "./packages/agent", diff --git a/packages/adapters/deno.json b/packages/adapters/deno.json index 7ba0c770..60cb78df 100644 --- a/packages/adapters/deno.json +++ b/packages/adapters/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/adapters", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts", "./fsworker": "./src/fs/fsworker.ts", "./alist-mock": "./src/alist/mock.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/agent/deno.json b/packages/agent/deno.json index 1e9c0f8a..95b96844 100644 --- a/packages/agent/deno.json +++ b/packages/agent/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/agent", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/contracts/deno.json b/packages/contracts/deno.json index d5569ca9..334f4f48 100644 --- a/packages/contracts/deno.json +++ b/packages/contracts/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/contracts", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/db/deno.json b/packages/db/deno.json index e111ea2f..12f2c5a0 100644 --- a/packages/db/deno.json +++ b/packages/db/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/db", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/domain/deno.json b/packages/domain/deno.json index f330b0bd..834b2be4 100644 --- a/packages/domain/deno.json +++ b/packages/domain/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/domain", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/mapping/deno.json b/packages/mapping/deno.json index 55e7556f..9e40432e 100644 --- a/packages/mapping/deno.json +++ b/packages/mapping/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/mapping", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/tasks/deno.json b/packages/tasks/deno.json index ce07f9fc..e3dae171 100644 --- a/packages/tasks/deno.json +++ b/packages/tasks/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/tasks", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run", diff --git a/packages/testkit/deno.json b/packages/testkit/deno.json index b942b555..f17ca7f0 100644 --- a/packages/testkit/deno.json +++ b/packages/testkit/deno.json @@ -1,6 +1,6 @@ { "name": "@umt/testkit", - "version": "0.3.38", + "version": "0.3.39", "exports": { ".": "./src/index.ts" }, "tasks": { "test": "deno run -A npm:vitest run",