"use server"; import { revalidatePath } from "next/cache"; import { getPaths } from "yt-dlp-transcript-common/lib/paths"; import { runManagedFunction } from "yt-dlp-transcript-common/jobs/streamCommand"; import { clearPlatformHold } from "yt-dlp-transcript-common/jobs/downloadBackoff"; // "CLEAR HOLD" (release 17 slice RL, review H2). The operator's word beats the // machine, as with an auto-pause: a held platform's hold, its backoff and its // raised pace all go, and the next failure starts the escalation from the // bottom. Run as a one-step job so the clearing is in a job log (/jobs, kind // `clear-platform-hold`), on its own queue — a Sync running on the platform's // queue must not make the click wait. export async function clearPlatformHoldAction( platform: string, ): Promise<{ ok: true; message: string } | { ok: false; error: string }> { if (!/^[a-z0-9.-]{1,64}$/i.test(platform)) { return { ok: false, error: `Not a platform: ${platform}` }; } const paths = getPaths(); let message = `${platform} had no hold, backoff or raised pace to clear.`; const res = await runManagedFunction({ kind: "clear-platform-hold", queueKey: `pacing:${platform}`, paths, fn: async (onLog) => { const line = await clearPlatformHold(platform, paths); if (line) message = line.trim(); onLog(`${message}\n`); }, }); if (!res.ok) return { ok: false, error: res.error }; void res.stream.cancel(); const done = await res.done; if (done.status !== "done") { return { ok: false, error: `Clearing the ${platform} hold ended ${done.status}.` }; } revalidatePath("/operations"); revalidatePath("/operations/[id]", "page"); return { ok: true, message }; }