From 4fa1f57351de6ef31ff181841f3f9cfbb26a87c2 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Mon, 23 Feb 2026 18:26:47 -0500 Subject: [PATCH] feat: improve timeout handling in archiveHandler and refactor handleMonolith for better signal management --- apps/worker/lib/archiveHandler.ts | 8 ++- .../lib/preservationScheme/handleMonolith.ts | 50 ++++++------------- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/apps/worker/lib/archiveHandler.ts b/apps/worker/lib/archiveHandler.ts index 851addb9..a1b3e338 100644 --- a/apps/worker/lib/archiveHandler.ts +++ b/apps/worker/lib/archiveHandler.ts @@ -57,8 +57,10 @@ export default async function archiveHandler( } const abortController = new AbortController(); + let timeoutId: NodeJS.Timeout | undefined; + const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => { + timeoutId = setTimeout(() => { abortController.abort(); reject( new Error( @@ -209,6 +211,10 @@ export default async function archiveHandler( console.log("Reason:", err); throw err; } finally { + if (timeoutId !== undefined) { + clearTimeout(timeoutId); + } + const finalLink = await prisma.link.findUnique({ where: { id: link.id }, }); diff --git a/apps/worker/lib/preservationScheme/handleMonolith.ts b/apps/worker/lib/preservationScheme/handleMonolith.ts index 772f0956..23b9eac1 100644 --- a/apps/worker/lib/preservationScheme/handleMonolith.ts +++ b/apps/worker/lib/preservationScheme/handleMonolith.ts @@ -25,17 +25,10 @@ export default async function handleMonolith( const child = spawn("monolith", args, { stdio: ["pipe", "pipe", "inherit"], - detached: true, + signal, + killSignal: "SIGKILL", }); - const abortListener = () => { - try { - if (child.pid) killProcess(child.pid); - } catch {} - reject(new Error("Monolith aborted")); - }; - signal?.addEventListener("abort", abortListener); - child.stdin.write(htmlFromPage); child.stdin.end(); @@ -43,14 +36,11 @@ export default async function handleMonolith( child.stdout.on("data", (c) => chunks.push(c)); child.on("error", (err) => { - cleanup(); reject(err); }); child.on("close", async (code) => { - cleanup(); - - if (code !== 0) { + if (code !== 0 && code !== null) { return reject(new Error(`Monolith exited with code ${code}`)); } @@ -64,29 +54,21 @@ export default async function handleMonolith( return reject(new Error("Monolith output exceeded buffer limit")); } - await createFile({ - data: html, - filePath: `archives/${link.collectionId}/${link.id}.html`, - }); + try { + await createFile({ + data: html, + filePath: `archives/${link.collectionId}/${link.id}.html`, + }); - await prisma.link.update({ - where: { id: link.id }, - data: { monolith: `archives/${link.collectionId}/${link.id}.html` }, - }); + await prisma.link.update({ + where: { id: link.id }, + data: { monolith: `archives/${link.collectionId}/${link.id}.html` }, + }); - resolve(); + resolve(); + } catch (err) { + reject(err); + } }); - - function cleanup() { - signal?.removeEventListener("abort", abortListener); - } }); } - -const killProcess = async (PID: number) => { - if (process.platform === "win32") { - process.kill(PID, "SIGKILL"); - } else { - process.kill(-PID, "SIGKILL"); - } -};