feat: improve timeout handling in archiveHandler and refactor handleMonolith for better signal management

This commit is contained in:
daniel31x13
2026-02-23 18:26:47 -05:00
parent f3d30085de
commit 4fa1f57351
2 changed files with 23 additions and 35 deletions

View File

@@ -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 },
});

View File

@@ -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");
}
};