refactor(server): clean up close listener and avoid writing 499 to dead socket

Wrap the long-poll handler in try/finally to detach the req.raw close
listener on every resolution path, and use reply.hijack() on the aborted
branch so Fastify does not attempt to write to a socket that's already
closed (which would otherwise emit per-disconnect log noise once the
watcher relaunch loop is busy). Behavior on the wire is unchanged for
the four documented status codes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mika Kuns
2026-05-20 16:23:48 +02:00
parent b05e6f2bd7
commit 8169ebf4fe

View File

@@ -145,8 +145,9 @@ export async function buildServer(cfg: DaemonConfig, store: MailboxStore): Promi
}
const ac = new AbortController();
req.raw.on("close", () => ac.abort());
const onClose = (): void => ac.abort();
req.raw.once("close", onClose);
try {
const result = await store.waitForMessage(name, timeoutS * 1000, ac.signal);
if (result.kind === "message") {
@@ -162,9 +163,12 @@ export async function buildServer(cfg: DaemonConfig, store: MailboxStore): Promi
reply.code(204);
return reply.send();
}
// aborted — client gone, no response needed (Fastify will swallow).
reply.code(499);
return reply.send();
// aborted — client gone; hand control to Fastify without writing to the dead socket.
reply.hijack();
return;
} finally {
req.raw.off("close", onClose);
}
},
);