fix(acquisition): 同一种子被别的计划占用而取消的计划不让位,避免 B/C 两线合并后取消 → 重评 → 再取消的空转

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 21:23:52 +08:00
1 parent 15d7f2ec2f
commit 5b023ad682
2 files changed
+22 -2

No files matched your search

@@ -1103,12 +1103,18 @@ export function subscriptionSavePath(t: Pick<InstanceTopology, "inst" | "mapping
/**
* 旧计划是否让位给新计划(T1-3c):失败 / 取消 / 过期可以重建(站点 Cookie 修好、下载器恢复、集数映射改号后重评),
* 但用户明确不要的(在下载器里移除、手动取消)和整理阶段失败的(文件已下好,重下同一种子无意义,交给整理重试)仍挡住。
* 但用户明确不要的(在下载器里移除、手动取消)和整理阶段失败的(文件已下好,重下同一种子无意义,交给整理重试)仍挡住;
* 同一种子已被别的计划占用而取消的(torrent_in_use_by_plan)也挡住,否则取消即重评、重评又撞上同一任务,来回空转。
*/
function planRetryable(p: { status: string; status_reason: string | null }): boolean {
if (!["failed", "cancelled", "expired"].includes(p.status)) return false;
const r = p.status_reason ?? "";
return r !== "download_removed" && r !== "cancelled_by_user" && !r.startsWith("organize:");
return (
r !== "download_removed" &&
r !== "cancelled_by_user" &&
!r.startsWith("organize:") &&
!r.startsWith("torrent_in_use_by_plan")
);
}
async function reserve(